diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index 19f864f13d..0000000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,25 +0,0 @@ -**Arma 3 Version:** `x.xx` (stable / rc / dev) -**CBA Version:** `3.x.x` (stable / dev + commit hash) -**ACE3 Version:** `3.x.x` (stable / dev + commit hash) - -**Mods:** -``` -- CBA_A3 -- ace -``` - -**Description:** -- Add a detailed description of the error. This makes it easier for us to fix the issue. - -**Steps to reproduce:** -- Add the steps needed to reproduce the issue. - -**Where did the issue occur?** -- Dedicated / Self-Hosted Multiplayer / Singleplayer / Editor (Singleplayer) / Editor (Multiplayer) / Virtual Arsenal - -**Additional information:** -- Provide any additional information that will help us solve this issue. - -**RPT log file:** -- Add a link ([gist](https://gist.github.com) or [pastebin](http://pastebin.com)) to the client and/or server RPT file. An instruction to find your RPT files can be found [here](https://community.bistudio.com/wiki/Crash_Files#Arma_3). -- If possible at the time the bug is encountered, go to Options and select "ACE Debug To Clipboard", this will print extensive debug information to the RPT file and copy it to clipboard. diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000000..f99743deec --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,37 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: kind/bug +assignees: '' + +--- + +**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] +_Make sure to reproduce the issue with only CBA and ACE3 on a newly created mission!_ + +**Description:** +A clear and concise description of what the bug is. + +**Steps to reproduce:** +- Go to ... +- Click ... +- See ... + +**Expected behavior:** +A clear and concise description of what you expected to happen. + +**Where did the issue occur?** +- Dedicated / Self-Hosted Multiplayer / Singleplayer / Editor (Singleplayer) / Editor (Multiplayer) / Virtual Arsenal + +**Log Files:** +- Link to ([gist](https://gist.github.com) or [pastebin](http://pastebin.com)) to the client and/or server RPT file. An instruction to find your RPT files can be found [here](https://community.bistudio.com/wiki/Crash_Files#Arma_3). + +**Additional context:** +Add any other context about the problem here. + +**Screenshots:** +If applicable, add screenshots to help explain your problem. diff --git a/.github/ISSUE_TEMPLATE/enhancement-request.md b/.github/ISSUE_TEMPLATE/enhancement-request.md new file mode 100644 index 0000000000..e4f5abcb54 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/enhancement-request.md @@ -0,0 +1,20 @@ +--- +name: Enhancement request +about: Suggest an improvement for this project +title: '' +labels: kind/enhancement +assignees: '' + +--- + +**Is your enhancement related to a problem?** +A clear and concise description of what the enhancement entails. Ex. [...] would improve user experience. + +**Solution you'd like:** +A clear and concise description of what you want to happen. + +**Alternatives you've considered:** +A clear and concise description of any alternative solutions or ideas you've considered. + +**Additional context:** +Add any other context or screenshots about the enhancement here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000000..45e10cf0cb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,12 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: kind/feature request, status/invalid +assignees: '' + +--- + +### Do not post feature requests here! + +Learn how to make a feature request [here](https://ace3mod.com/wiki/user/how-to-make-a-feature-request.html). diff --git a/.github/workflows/arma.yml b/.github/workflows/arma.yml new file mode 100644 index 0000000000..528a9306c9 --- /dev/null +++ b/.github/workflows/arma.yml @@ -0,0 +1,45 @@ +name: Arma + +on: + push: + branches: + - master + pull_request: + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - name: Checkout the source code + uses: actions/checkout@master + - name: Validate SQF + run: python3 tools/sqf_validator.py + - name: Validate Config + run: python3 tools/config_style_checker.py + - name: Validate String Tables + run: python3 tools/check_strings.py + - name: Check for BOM + uses: arma-actions/bom-check@master + + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout the source code + uses: actions/checkout@master + - name: Lint (sqflint) + uses: arma-actions/sqflint@master + continue-on-error: true # No failure due to many false-positives + + build: + runs-on: ubuntu-latest + container: acemod/armake:master + steps: + - name: Checkout the source code + uses: actions/checkout@master + - name: Build (armake) + run: armake --version && make -j4 + - name: Upload Artifact + uses: actions/upload-artifact@master + with: + name: ace3-${{ github.sha }}-nobin + path: '@ace' diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml new file mode 100644 index 0000000000..5022af32f4 --- /dev/null +++ b/.github/workflows/documentation.yml @@ -0,0 +1,24 @@ +name: Documentation + +on: + push: + branches: + - master + +jobs: + update: + runs-on: ubuntu-latest + steps: + - name: Checkout the source code + uses: actions/checkout@master + - name: Install Python packages + run: | + pip3 install wheel + pip3 install setuptools + pip3 install pygithub + pip3 install pygithub3 + - name: Deploy + if: github.repository == 'acemod/ACE3' && ! contains(github.event.head_commit.message, '[ci skip]') + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: python3 tools/deploy.py diff --git a/.github/workflows/extensions.yml b/.github/workflows/extensions.yml new file mode 100644 index 0000000000..62b3ee6961 --- /dev/null +++ b/.github/workflows/extensions.yml @@ -0,0 +1,30 @@ +name: Extensions + +on: + pull_request: + paths: + - 'extensions/*' + - 'extensions/*/*' + - 'extensions/*/*/*' + - 'extensions/*/*/*/*' + - 'extensions/*/*/*/*/*' + +jobs: + build: + runs-on: ${{ matrix. os }} + strategy: + matrix: + os: [windows-latest] + + steps: + - name: Checkout the source code + uses: actions/checkout@master + - name: Build + run: | + cd extensions/build + cmake .. && cmake --build . + - name: Upload Artifact + uses: actions/upload-artifact@master + with: + name: ace3_extensions-${{ matrix.os }}-debug + path: extensions/build diff --git a/AUTHORS.txt b/AUTHORS.txt index 29861f1e50..e05d1d7d11 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -47,10 +47,12 @@ Arkhir Asgar Serran BaerMitUmlaut Bamse +Barman75 Bla1337 BlackPixxel BlackQwar Brakoviejo +Brandon (TCVM) Brisse Brostrom.A | Evul BullHorn @@ -60,6 +62,7 @@ Clon1998 Codingboy Coren Crusty +C0kkie Dharma Bellamkonda Dimaslg diwako @@ -130,6 +133,7 @@ Riccardo Petricca Robert Boklahánics ruPaladin Rutger "RedBery" Meijering +Schwaggot simon84 Skengman2 Sniperwolf572 diff --git a/Makefile b/Makefile index 736994ecb4..f0b0810e3e 100644 --- a/Makefile +++ b/Makefile @@ -82,7 +82,7 @@ push: commit release: clean version commit @"$(MAKE)" $(MAKEFLAGS) signatures @echo " ZIP $(ZIP)_$(VERSION_S).zip" - @cp *.dll mod.cpp README.md docs/README_DE.md docs/README_PL.md AUTHORS.txt LICENSE logo_ace3_ca.paa meta.cpp $(BIN) + @cp *.dll *.so mod.cpp README.md docs/README_DE.md docs/README_PL.md AUTHORS.txt LICENSE logo_ace3_ca.paa meta.cpp $(BIN) @zip -qr $(ZIP)_$(VERSION_S).zip $(BIN) clean: diff --git a/README.md b/README.md index 74e32e1fac..eb794493a0 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ ACE3 License - ACE3 Slack + ACE3 Slack ACE3 Build Status diff --git a/ace_medical.dll b/ace_medical.dll deleted file mode 100644 index ede53b861d..0000000000 Binary files a/ace_medical.dll and /dev/null differ diff --git a/ace_medical_x64.dll b/ace_medical_x64.dll deleted file mode 100644 index d046ad1d7f..0000000000 Binary files a/ace_medical_x64.dll and /dev/null differ diff --git a/addons/advanced_ballistics/config.cpp b/addons/advanced_ballistics/config.cpp index 488b812fc6..17647d0647 100644 --- a/addons/advanced_ballistics/config.cpp +++ b/addons/advanced_ballistics/config.cpp @@ -20,5 +20,8 @@ class CfgPatches { #include "ACE_Settings.hpp" class ACE_Extensions { - extensions[] += {"ace_advanced_ballistics"}; + class ace_advanced_ballistics { + windows = 1; + client = 1; + }; }; diff --git a/addons/advanced_ballistics/functions/fnc_initializeTerrainExtension.sqf b/addons/advanced_ballistics/functions/fnc_initializeTerrainExtension.sqf index 5c634cadff..8ff8052745 100644 --- a/addons/advanced_ballistics/functions/fnc_initializeTerrainExtension.sqf +++ b/addons/advanced_ballistics/functions/fnc_initializeTerrainExtension.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" /* * Author: Ruthberg - * Initializes the advanced ballistics dll extension with terrain data + * Initializes the advanced ballistics extension with terrain data * * Arguments: * None diff --git a/addons/advanced_ballistics/stringtable.xml b/addons/advanced_ballistics/stringtable.xml index 09d992a769..118057afe0 100644 --- a/addons/advanced_ballistics/stringtable.xml +++ b/addons/advanced_ballistics/stringtable.xml @@ -91,6 +91,8 @@ 启用枪口初速变化 Activer les variations de la vitesse initiale Aktywuj wariację prędkości wylotowej + Вкл. вариацию начальной скорости + Ativar Variação de Velocidade no Freio de boca (muzzle) Simulates slight variations in muzzle velocity between each shot @@ -102,6 +104,8 @@ 模拟每发子弹的枪口初速都略有不同 Simule les légères variations Symuluje lekkie zmiany w prędkości wylotowej między każdym strzałem + Имитирует небольшие изменения начальной скорости при каждом выстреле + Simula pequenas variações na velocidade do Freio de Boca entre cada tiro Enable Ammo Temperature Simulation diff --git a/addons/advanced_fatigue/XEH_postInit.sqf b/addons/advanced_fatigue/XEH_postInit.sqf index 2227cd6540..78027fd3f5 100644 --- a/addons/advanced_fatigue/XEH_postInit.sqf +++ b/addons/advanced_fatigue/XEH_postInit.sqf @@ -47,8 +47,8 @@ if (!hasInterface) exitWith {}; [QEGVAR(medical,pain), { // 0->1.0, 0.5->1.05, 1->1.1 linearConversion [0, 1, (_this getVariable [QEGVAR(medical,pain), 0]), 1, 1.1, true]; }] call FUNC(addDutyFactor); - [QEGVAR(medical,bloodVolume), { // 100->1.0, 90->1.1, 80->1.2 - linearConversion [6, 0, (_this getVariable [QEGVAR(medical,bloodVolume), 100]), 1, 2, true]; + [QEGVAR(medical,bloodVolume), { // 6->1.0, 5->1.167, 4->1.33 + linearConversion [6, 0, (_this getVariable [QEGVAR(medical,bloodVolume), 6]), 1, 2, true]; }] call FUNC(addDutyFactor); }; if (["ACE_Dragging"] call EFUNC(common,isModLoaded)) then { diff --git a/addons/advanced_fatigue/XEH_preInit.sqf b/addons/advanced_fatigue/XEH_preInit.sqf index 1cb60db917..12f007ccf6 100644 --- a/addons/advanced_fatigue/XEH_preInit.sqf +++ b/addons/advanced_fatigue/XEH_preInit.sqf @@ -10,5 +10,6 @@ PREP_RECOMPILE_END; GVAR(staminaBarWidth) = 10 * (((safezoneW / safezoneH) min 1.2) / 40); GVAR(dutyList) = [[], []]; +GVAR(setAnimExclusions) = []; ADDON = true; diff --git a/addons/advanced_fatigue/functions/fnc_handleEffects.sqf b/addons/advanced_fatigue/functions/fnc_handleEffects.sqf index 1283d86555..fbbb685217 100644 --- a/addons/advanced_fatigue/functions/fnc_handleEffects.sqf +++ b/addons/advanced_fatigue/functions/fnc_handleEffects.sqf @@ -58,8 +58,9 @@ if (GVAR(ppeBlackoutLast) == 1) then { // - Physical effects --------------------------------------------------------- if (GVAR(isSwimming)) exitWith { - _unit setAnimSpeedCoef linearConversion [0.7, 0.9, _fatigue, 1, 0.5, true]; - + if (GVAR(setAnimExclusions) isEqualTo []) then { + _unit setAnimSpeedCoef linearConversion [0.7, 0.9, _fatigue, 1, 0.5, true]; + }; if ((isSprintAllowed _unit) && {_fatigue > 0.7}) then { [_unit, "blockSprint", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); } else { @@ -69,7 +70,10 @@ if (GVAR(isSwimming)) exitWith { }; }; if ((getAnimSpeedCoef _unit) != 1) then { - _unit setAnimSpeedCoef 1; + if (GVAR(setAnimExclusions) isEqualTo []) then { + TRACE_1("reset",getAnimSpeedCoef _unit); + _unit setAnimSpeedCoef 1; + }; }; if (_overexhausted) then { diff --git a/addons/advanced_fatigue/stringtable.xml b/addons/advanced_fatigue/stringtable.xml index 8fb6bc7e5e..73c4f83624 100644 --- a/addons/advanced_fatigue/stringtable.xml +++ b/addons/advanced_fatigue/stringtable.xml @@ -11,6 +11,8 @@ ACE 고급 피로도 ACE Fatigue Avancée ACE Zaawansowane Zmęczenie + ACE Продвинутая усталость + ACE Fadiga Avançada Performance Factor @@ -22,6 +24,8 @@ Fattore Prestazione 體力值 体力值 + Фактор производительности + Fator de Performance Influences the overall performance of all players with no custom factor. Higher means better. @@ -33,6 +37,8 @@ Influenza qualsiasi prestazione 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. Influences the overall performance of this unit. Higher means better. @@ -44,6 +50,8 @@ Influenza qualsiasi prestazione di questa unità. Maggiore significa migliore. 影響這個單位的體力表現,值越高代表體力越好 影响这个单位的体力表现,值越高代表体力越好 + Влияет на общую производительность юнита. + Influencia na performance geral dessa unidade. Quanto maior, melhor. Recovery Factor @@ -55,6 +63,8 @@ Fattore Recupero 回復值 回复值 + Фактор восстановления + Fator de Recuperação Changes how fast the player recovers when resting. Higher is faster. @@ -66,6 +76,8 @@ Determina in quanto tempo il giocatore recupera quando rilassato. Maggiore significa migliore. 決定玩家休息多久就能回復體力,值越高恢復越快 决定玩家休息多久就能回复体力,值越高恢复越快 + Изменяет скорость восстановления игрока во время отдыха. Чем выше, тем быстрее. + Altera o quão rápido um jogador recupera quando descansando. Quanto maior, mais rápido. Load Factor @@ -77,6 +89,8 @@ Fattore Caricamento 負重量 负重量 + Фактор нагрузки + Fator de Carga Increases or decreases how much weight influences the players performance. Zero means equipment weight has no performance influence. @@ -88,6 +102,8 @@ Incrementa o decrementa quanto il peso influenza le prestazioni dei giocatori. Zero significa che il peso dell'equipaggiamento non ha alcuna influenza nelle prestazioni. 增加或降低玩家所能承受的負重量. 如設定值為0, 代表裝備的重量將不會影響到玩家的體力表現 增加或降低玩家所能承受的负重量. 如设定值为0, 代表装备的重量将不会影响到玩家的体力表现 + Увеличивает или уменьшает вес, влияющий на производительность игроков. Ноль означает, что вес снаряжения не влияет на производительность + Aumenta ou diminui o quanto o peso influencia a performance do jogador. Zero significa que o peso não tem impacto algum na performance. Terrain Gradient Factor @@ -99,6 +115,8 @@ Fattore Pendenza Terreno 地形陡峭影響值 地形陡峭影响值 + Фактор местности + Fator de Inclinação do Terreno Sets how much steep terrain increases stamina loss. Higher means higher stamina loss. @@ -110,24 +128,32 @@ Stabilisce 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. Sway factor + Verwacklungsfaktor 手ぶれ因数 抖动因数 抖動因素 Facteur de stabilisation Fattore di oscillazione Czynnik kołysania + Фактор колебания прицела + Fator de Balanço de Mira Influences the amount of weapon sway. Higher means more sway. + Beeinflusst den Faktor, wie ruhig man eine Waffe halten kann. Ein höherer Wert bedeutet weniger Stabilisierung 武器を持つ手のぶれ度合いを設定します。 値が高ければ高いほど、手ぶれが強くなります。 影响手持武器的晃动程度,数值越高,抖动的越厉害. 影響手持武器晃動程度,數值越高抖動越厲害 Influence les mouvements de l'arme, une valeur plus élevée signifie plus de mouvements 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. Enabled @@ -139,6 +165,8 @@ Abilitato 啟用 启用 + Включена + Ativado Enables/disables Advanced Fatigue. @@ -150,6 +178,8 @@ Abilita/disabilita la Fatica Avanzata. 啟用/關閉進階體力. 启用/关闭进阶体力. + Включает / Отключает Продвинутую усталость + Ativa/Desativa Fadiga Avançada. Show stamina bar @@ -161,6 +191,8 @@ Mostra barra stamina 顯示體力條 显示体力条 + Показать шкалу усталости + Exibir barra de estamina Shows the stamina bar. @@ -172,6 +204,8 @@ Mostra la barra della stamina. 顯示體力條 显示体力条 + Показывает шкалу усталости. + Exibe a barra de estamina. diff --git a/addons/advanced_throwing/functions/fnc_throwFiredXEH.sqf b/addons/advanced_throwing/functions/fnc_throwFiredXEH.sqf index 80dbc2f973..5461d5d010 100644 --- a/addons/advanced_throwing/functions/fnc_throwFiredXEH.sqf +++ b/addons/advanced_throwing/functions/fnc_throwFiredXEH.sqf @@ -26,3 +26,8 @@ TRACE_1("Fired",_this); { _this call _x; } forEach ((_this select 0) getVariable "cba_xeh_fired"); + +// Call muzzle fired EH +{ + _this call compile getText (_x >> "fired"); +} forEach (configProperties [configFile >> "CfgWeapons" >> "Throw" >> (_this select 2) >> "EventHandlers", "isClass _x", true]); diff --git a/addons/advanced_throwing/stringtable.xml b/addons/advanced_throwing/stringtable.xml index a060927076..08042e09ea 100644 --- a/addons/advanced_throwing/stringtable.xml +++ b/addons/advanced_throwing/stringtable.xml @@ -12,6 +12,7 @@ Lancio Avanzato 進階投擲 进阶投掷 + Arremesso Avançado Allows changing advanced throwing behaviour. @@ -24,6 +25,7 @@ Permette il cambiamento della modalità di tiro. 允許使用更多不同的投擲方式 允许使用更多不同的投掷方式 + Permite mudar o comportamento do arremesso avançado. Enable Advanced Throwing @@ -36,6 +38,7 @@ Abilita Lancio Avanzato 啟用進階投擲 启用进阶投掷 + Ativa o Arremesso Avançado Enables advanced throwing system. @@ -48,6 +51,7 @@ Abilita il sistema di lancio avanzato. 啟用進階投擲系統 启用进阶投掷系统 + Ativa o sistema de Arremesso Avançado. Show Throw Arc @@ -60,6 +64,7 @@ Mostra Arco di Tiro 顯示投擲軌道 显示投掷轨道 + Mostrar o Arco de Arremesso Enables visualization of the throw arc (where throwable will fly). @@ -72,6 +77,7 @@ Abilita la visualizzazione dell'arco del tiro (dove l'oggetto lanciabile volerà). 顯示投擲軌道幫助投擲 显示投掷轨道帮助投掷 + Permite a visualização do Arco de Arremesso por onde o objeto será jogado. Show Throwing Mouse Controls @@ -84,6 +90,7 @@ Mostra Comandi Mouse Lancio 顯示滑鼠投擲控制提示 显示滑鼠投掷控制提示 + Mostrar os controles de mouse para Arremesso Enables visual cues for mouse controls when throwable is prepared. @@ -96,6 +103,7 @@ Abilita la visualizzazione dei controlli del mouse quando l'oggetto lanciabile è pronto. 開啟後會在準備投擲時, 顯示滑鼠相關操作 开启后会在准备投掷时, 显示滑鼠相关操作 + Ativa as dicas visuais dos controles do mouse quando um arremessável é preparado. Enable Throwables Pick Up @@ -108,6 +116,7 @@ Abilita Raccogli Oggetti 啟用可撿取地面投擲物 启用可捡取地面投掷物 + Permitir pegar arremessáveis Enables ability to pick up throwables from the ground. @@ -120,6 +129,7 @@ Abilita la possibilità di raccogliere un oggetto lanciabile da terra. 啟用後, 可撿取地面上的投擲物 启用后, 可捡取地面上的投掷物 + Permite que objetos arremessados sejam pegos do chão. (ACE Menu de Interação) Enable Attached Throwables Pick Up @@ -132,6 +142,7 @@ Abilita Raccogli Oggetti Lanciabili da altri Oggetti 啟用可撿取附著投擲物 启用可捡取附着投掷物 + Permitir pegar arremessáveis fixados Enables ability to pick up throwables from attached objects. @@ -144,6 +155,7 @@ Abilita la possibilità di raccogliere gli oggetti lanciabili dagli altri oggetti. 啟用後, 可撿取附著在物件上的投擲物 启用后, 可捡取附着在物件上的投掷物 + Permite que arremessáveis fixados em objetos sejam pegos. Prepare/Change Throwable @@ -156,6 +168,7 @@ Prepara/Cambia Oggetto lanciabile 準備/變更投擲物 准备/变更投掷物 + Preparar/Mudar Arremessável Throwable Drop Mode (Hold) @@ -168,6 +181,7 @@ Modalità Oggetto Gettabile (Mantenere) 投擲模式 (按住) 投掷模式 (按住) + Modo de Arremesso (Segurar) Throwable Drop Mode (Toggle) @@ -180,6 +194,7 @@ Modalità Oggetto lanciabile Gettabile (Interruttore) 投擲模式 (切換) 投掷模式 (切换) + Modo de Arremesso (Alternar) Primed @@ -192,6 +207,7 @@ Armato 引信開始燃燒 引信开始燃烧 + Preparado Throw @@ -204,6 +220,7 @@ Lanciare 投擲 投掷 + Arremessar (Scroll) Change Mode @@ -216,6 +233,7 @@ (Scorrere) Cambio Modalità (滾輪) 變更模式 (滚轮) 变更模式 + (Roda do Mouse) Alternar modo (Scroll) Extend @@ -228,6 +246,7 @@ (Scorrere) Estendere (滾輪) 延長 (滚轮) 延长 + (Roda do Mouse) Extender (Click) Cook @@ -240,6 +259,7 @@ (Click) Arma (點擊) 提早拉開引信 (点击) 提早拉开引信 + (Clique) Cozinhar Pick Up @@ -252,6 +272,7 @@ Raccogli 撿取 捡取 + Pegar diff --git a/addons/ai/stringtable.xml b/addons/ai/stringtable.xml index 59dca33cb4..6a307a500e 100644 --- a/addons/ai/stringtable.xml +++ b/addons/ai/stringtable.xml @@ -3,6 +3,7 @@ Invalid position provided. + Ungültige Position Position invalide fourni 位置が無効です。 Posizione invalida fornita. @@ -10,9 +11,12 @@ 提供的位置无效。 위치가 잘못되었습니다. Podano błędną pozycję. + Указана неверная позиция + Posição inválida fornecida. No units provided. + Keine Einheit ausgewählt Aucune unité fourni ユニットがありません。 Nessuna unità fornita. @@ -20,9 +24,12 @@ 找不到可用的单位。 병력이 없습니다. Nie podano żadnych jednostek. + Не указаны юниты + Nenhuma unidade fornecida. There aren't enough positions to place all units. + Es gibt nicht genug Positionen, um alle Einheiten zu platzieren Il n'y a pas assez de positions pour placer toutes les unités 全ユニットを置くために十分な位置がありません。 Non ci sono abbastanza posizioni per piazzare tutte le unità. @@ -30,9 +37,12 @@ 没有足够的位置能摆放所有单位。 모든 병력을 배치 할 공간이 없습니다. Nie ma wystarczającej ilości pozycji, aby umieścić wszystkie jednostki. + Недостаточно позиций для размещения всех юнитов + Não há posições suficientes para colocar todas as unidades. No building found. + Kein Gebäude gefunden Aucun bâtiment trouvé 建物がありません。 Nessun edificio trovato. @@ -40,6 +50,8 @@ 没找到建筑物。 건물이 없습니다. Nie znaleziono budynku. + Здание не найдено + Nenhuma construção encontrada. diff --git a/addons/apl/ACE_CSW_Bag.p3d b/addons/apl/ACE_CSW_Bag.p3d new file mode 100644 index 0000000000..d80bde086d Binary files /dev/null and b/addons/apl/ACE_CSW_Bag.p3d differ diff --git a/addons/apl/ACE_CSW_m3_tripod.p3d b/addons/apl/ACE_CSW_m3_tripod.p3d new file mode 100644 index 0000000000..0ad274ad9c Binary files /dev/null and b/addons/apl/ACE_CSW_m3_tripod.p3d differ diff --git a/addons/apl/ACE_CSW_mortarBaseplate.p3d b/addons/apl/ACE_CSW_mortarBaseplate.p3d new file mode 100644 index 0000000000..1dfee12c2a Binary files /dev/null and b/addons/apl/ACE_CSW_mortarBaseplate.p3d differ diff --git a/addons/apl/ace_csw_tripod_ags30.p3d b/addons/apl/ace_csw_tripod_ags30.p3d new file mode 100644 index 0000000000..11dd8fc0f2 Binary files /dev/null and b/addons/apl/ace_csw_tripod_ags30.p3d differ diff --git a/addons/apl/ace_csw_tripod_kord.p3d b/addons/apl/ace_csw_tripod_kord.p3d new file mode 100644 index 0000000000..f2c1d67410 Binary files /dev/null and b/addons/apl/ace_csw_tripod_kord.p3d differ diff --git a/addons/apl/ace_csw_tripod_m122.p3d b/addons/apl/ace_csw_tripod_m122.p3d new file mode 100644 index 0000000000..90cf2157ab Binary files /dev/null and b/addons/apl/ace_csw_tripod_m122.p3d differ diff --git a/addons/apl/ace_csw_tripod_m220.p3d b/addons/apl/ace_csw_tripod_m220.p3d new file mode 100644 index 0000000000..c3632b12c3 Binary files /dev/null and b/addons/apl/ace_csw_tripod_m220.p3d differ diff --git a/addons/apl/ace_csw_tripod_spg9.p3d b/addons/apl/ace_csw_tripod_spg9.p3d new file mode 100644 index 0000000000..1b5ede50fd Binary files /dev/null and b/addons/apl/ace_csw_tripod_spg9.p3d differ diff --git a/addons/apl/data/csw_nsv.rvmat b/addons/apl/data/csw_nsv.rvmat new file mode 100644 index 0000000000..46ea387b23 --- /dev/null +++ b/addons/apl/data/csw_nsv.rvmat @@ -0,0 +1,95 @@ +ambient[]={1,1,1,1.000000}; +diffuse[]={1,1,1,1.000000}; +forcedDiffuse[]={0.000000,0.000000,0.000000,0.000000}; +emmisive[]={0.000000,0.000000,0.000000,1.000000}; +specular[]={1,1,1,1.000000}; +specularPower=40.000000; +PixelShaderID="super"; +VertexShaderID="super"; +class Stage1 +{ + texture = "z\ace\addons\apl\data\csw_nsv_nohq.paa"; + uvSource="tex"; + class uvTransform + { + aside[]={1.000000,0.000000,0.000000}; + up[]={0.000000,1.000000,0.000000}; + dir[]={0.000000,0.000000,0.000000}; + pos[]={0.000000,0.000000,0.000000}; + }; +}; +class Stage2 +{ + texture="a3\weapons_f\Data\DetailMaps\metal_detail_dt.paa"; + uvSource="tex"; + class uvTransform + { + aside[]={8.0000,0.000000,0.000000}; + up[]={0.000000,8.0000,0.000000}; + dir[]={0.000000,0.000000,0.000000}; + pos[]={0.000000,0.000000,0.000000}; + }; +}; +class Stage3 +{ + texture="#(argb,8,8,3)color(0,0,0,0,MC)"; + uvSource="tex"; + class uvTransform + { + aside[]={1.000000,0.000000,0.000000}; + up[]={0.000000,1.000000,0.000000}; + dir[]={0.000000,0.000000,0.000000}; + pos[]={0.000000,0.000000,0.000000}; + }; +}; +class Stage4 +{ + texture = "#(argb,8,8,3)color(1,1,1,1,AS)"; + uvSource="tex"; + class uvTransform + { + aside[]={1.000000,0.000000,0.000000}; + up[]={0.000000,1.000000,0.000000}; + dir[]={0.000000,0.000000,0.000000}; + pos[]={0.000000,0.000000,0.000000}; + }; +}; +class Stage5 +{ + texture = "z\ace\addons\apl\data\csw_nsv_smdi.paa"; + uvSource="tex"; + class uvTransform + { + aside[]={1.000000,0.000000,0.000000}; + up[]={0.000000,1.000000,0.000000}; + dir[]={0.000000,0.000000,0.000000}; + pos[]={0.000000,0.000000,0.000000}; + }; +}; +class Stage6 +{ + texture = "#(ai,32,128,1)fresnel(3.38,5.33)"; + uvSource="tex"; + class uvTransform + { + aside[]={1.000000,0.000000,0.000000}; + up[]={0.000000,1.000000,0.000000}; + dir[]={0.000000,0.000000,0.000000}; + pos[]={0.000000,0.000000,0.000000}; + }; +}; +class Stage7 +{ + texture="a3\data_f\env_land_co.paa"; + uvSource="tex"; + class uvTransform + { + aside[]={1.000000,0.000000,0.000000}; + up[]={0.000000,1.000000,0.000000}; + dir[]={0.000000,0.000000,0.000000}; + pos[]={0.000000,0.000000,0.000000}; + }; +}; +class StageTI { + texture = "a3\data_f\default_vehicle_ti_ca.paa"; +}; diff --git a/addons/apl/data/csw_nsv_co.paa b/addons/apl/data/csw_nsv_co.paa new file mode 100644 index 0000000000..f7af35c0b8 Binary files /dev/null and b/addons/apl/data/csw_nsv_co.paa differ diff --git a/addons/apl/data/csw_nsv_nohq.paa b/addons/apl/data/csw_nsv_nohq.paa new file mode 100644 index 0000000000..299de50ad7 Binary files /dev/null and b/addons/apl/data/csw_nsv_nohq.paa differ diff --git a/addons/apl/data/csw_nsv_smdi.paa b/addons/apl/data/csw_nsv_smdi.paa new file mode 100644 index 0000000000..09f7758e75 Binary files /dev/null and b/addons/apl/data/csw_nsv_smdi.paa differ diff --git a/addons/apl/data/csw_spg9.rvmat b/addons/apl/data/csw_spg9.rvmat new file mode 100644 index 0000000000..21de1208fd --- /dev/null +++ b/addons/apl/data/csw_spg9.rvmat @@ -0,0 +1,92 @@ +ambient[] = {1.0,1.0,1.0,1.0}; +diffuse[] = {1.0,1.0,1.0,1.0}; +forcedDiffuse[] = {0.0,0.0,0.0,0.0}; +emmisive[] = {0.0,0.0,0.0,1.0}; +specular[] = {0.545,0.545,0.545,1.0}; +specularPower = 100.0; +PixelShaderID = "Super"; +VertexShaderID = "Super"; +class Stage1 +{ + texture = "z\ace\addons\apl\data\csw_spg9_nohq.paa"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,1.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; +class Stage2 +{ + texture = "a3\weapons_f\Data\DetailMaps\metal_detail_dt.paa"; + uvSource = "tex"; + class uvTransform + { + aside[] = {8.0,0.0,0.0}; + up[] = {0.0,2.0,0.0}; + dir[] = {0.0,0.0,1.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; +class Stage3 +{ + texture = "#(argb,8,8,3)color(0,0,0,0,MC)"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,1.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; +class Stage4 +{ + texture = "#(argb,8,8,3)color(1,1,1,1,AS)"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,1.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; +class Stage5 +{ + texture = "z\ace\addons\apl\data\csw_spg9_smdi.paa"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,1.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; +class Stage6 +{ + texture = "#(ai,32,128,1)fresnel(1.89,1.02)"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,1.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; +class Stage7 +{ + texture="a3\data_f\env_land_co.paa"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,1.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; diff --git a/addons/apl/data/csw_spg9_co.paa b/addons/apl/data/csw_spg9_co.paa new file mode 100644 index 0000000000..c7b6694e9b Binary files /dev/null and b/addons/apl/data/csw_spg9_co.paa differ diff --git a/addons/apl/data/csw_spg9_nohq.paa b/addons/apl/data/csw_spg9_nohq.paa new file mode 100644 index 0000000000..718e536492 Binary files /dev/null and b/addons/apl/data/csw_spg9_nohq.paa differ diff --git a/addons/apl/data/csw_spg9_smdi.paa b/addons/apl/data/csw_spg9_smdi.paa new file mode 100644 index 0000000000..345a664a12 Binary files /dev/null and b/addons/apl/data/csw_spg9_smdi.paa differ diff --git a/addons/apl/data/csw_tow_merge.rvmat b/addons/apl/data/csw_tow_merge.rvmat new file mode 100644 index 0000000000..55db8aba2a --- /dev/null +++ b/addons/apl/data/csw_tow_merge.rvmat @@ -0,0 +1,32 @@ +ambient[]={1.000000,1.000000,1.000000,1.000000}; +diffuse[]={1.000000,1.000000,1.000000,1.000000}; +forcedDiffuse[]={0.000000,0.000000,0.000000,0.000000}; +emmisive[]={0.000000,0.000000,0.000000,1.000000}; +specular[]={0.3000000,0.3000000,0.3000000,1.000000}; +specularPower=100.000000; +PixelShaderID="NormalMapSpecularDIMap"; +VertexShaderID="NormalMap"; +class Stage1 +{ + texture="z\ace\addons\apl\data\csw_tow_merge_nohq.paa"; + uvSource="tex"; + class uvTransform + { + aside[]={1.000000,0.000000,0.000000}; + up[]={0.000000,1.000000,0.000000}; + dir[]={0.000000,0.000000,0.000000}; + pos[]={0.000000,0.000000,0.000000}; + }; +}; +class Stage2 +{ + texture="z\ace\addons\apl\data\csw_tow_merge_smdi.paa"; + uvSource="tex"; + class uvTransform + { + aside[]={1.000000,0.000000,0.000000}; + up[]={0.000000,1.000000,0.000000}; + dir[]={0.000000,0.000000,0.000000}; + pos[]={0.000000,0.000000,0.000000}; + }; +}; \ No newline at end of file diff --git a/addons/apl/data/csw_tow_merge_co.paa b/addons/apl/data/csw_tow_merge_co.paa new file mode 100644 index 0000000000..5d16cd54d4 Binary files /dev/null and b/addons/apl/data/csw_tow_merge_co.paa differ diff --git a/addons/apl/data/csw_tow_merge_nohq.paa b/addons/apl/data/csw_tow_merge_nohq.paa new file mode 100644 index 0000000000..a02ec97769 Binary files /dev/null and b/addons/apl/data/csw_tow_merge_nohq.paa differ diff --git a/addons/apl/data/csw_tow_merge_smdi.paa b/addons/apl/data/csw_tow_merge_smdi.paa new file mode 100644 index 0000000000..91090de9b4 Binary files /dev/null and b/addons/apl/data/csw_tow_merge_smdi.paa differ diff --git a/addons/apl/data/csw_tripod_ags.rvmat b/addons/apl/data/csw_tripod_ags.rvmat new file mode 100644 index 0000000000..3e435eb6db --- /dev/null +++ b/addons/apl/data/csw_tripod_ags.rvmat @@ -0,0 +1,32 @@ +ambient[] = {1.0,1.0,1.0,1.0}; +diffuse[] = {1.0,1.0,1.0,1.0}; +forcedDiffuse[] = {0.0,0.0,0.0,0.0}; +emmisive[] = {0.0,0.0,0.0,0.0}; +specular[] = {0.3,0.3,0.3,1.0}; +specularPower = 256.0; +PixelShaderID = "NormalMapSpecularDIMap"; +VertexShaderID = "NormalMap"; +class Stage1 +{ + texture = "z\ace\addons\apl\data\csw_tripod_ags_nohq.paa"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; +class Stage2 +{ + texture = "z\ace\addons\apl\data\csw_tripod_ags_smdi.paa"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; diff --git a/addons/apl/data/csw_tripod_ags_co.paa b/addons/apl/data/csw_tripod_ags_co.paa new file mode 100644 index 0000000000..93e2367188 Binary files /dev/null and b/addons/apl/data/csw_tripod_ags_co.paa differ diff --git a/addons/apl/data/csw_tripod_ags_nohq.paa b/addons/apl/data/csw_tripod_ags_nohq.paa new file mode 100644 index 0000000000..ddad36a44a Binary files /dev/null and b/addons/apl/data/csw_tripod_ags_nohq.paa differ diff --git a/addons/apl/data/csw_tripod_ags_smdi.paa b/addons/apl/data/csw_tripod_ags_smdi.paa new file mode 100644 index 0000000000..561bcc8178 Binary files /dev/null and b/addons/apl/data/csw_tripod_ags_smdi.paa differ diff --git a/addons/apl/data/m3tripod.rvmat b/addons/apl/data/m3tripod.rvmat new file mode 100644 index 0000000000..1739f48550 --- /dev/null +++ b/addons/apl/data/m3tripod.rvmat @@ -0,0 +1,98 @@ +#define _ARMA_ + +ambient[] = {1,1,1,1.0}; +diffuse[] = {1,1,1,1.0}; +forcedDiffuse[] = {0.0,0.0,0.0,0.0}; +emmisive[] = {0.0,0.0,0.0,1.0}; +specular[] = {1,1,1,1.0}; +specularPower = 40.0; +PixelShaderID = "super"; +VertexShaderID = "super"; +class Stage1 +{ + texture = "z\ace\addons\apl\data\m3tripod_nohq.paa"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; +class Stage2 +{ + texture = "a3\weapons_f\Data\DetailMaps\metal_detail_dt.paa"; + uvSource = "tex"; + class uvTransform + { + aside[] = {8.0,0.0,0.0}; + up[] = {0.0,8.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; +class Stage3 +{ + texture = "#(argb,8,8,3)color(0,0,0,0,MC)"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; +class Stage4 +{ + texture = "#(argb,8,8,3)color(1,1,1,1,AS)"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; +class Stage5 +{ + texture = "z\ace\addons\apl\data\m3tripod_SMDI.paa"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; +class Stage6 +{ + texture = "#(ai,32,128,1)fresnel(3.38,5.33)"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; +class Stage7 +{ + texture = "a3\data_f\env_land_co.paa"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; +class StageTI +{ + texture = "a3\data_f\default_vehicle_ti_ca.paa"; +}; diff --git a/addons/apl/data/m3tripod_co.paa b/addons/apl/data/m3tripod_co.paa new file mode 100644 index 0000000000..994bf342cc Binary files /dev/null and b/addons/apl/data/m3tripod_co.paa differ diff --git a/addons/apl/data/m3tripod_nohq.paa b/addons/apl/data/m3tripod_nohq.paa new file mode 100644 index 0000000000..46c64a4f48 Binary files /dev/null and b/addons/apl/data/m3tripod_nohq.paa differ diff --git a/addons/apl/data/m3tripod_smdi.paa b/addons/apl/data/m3tripod_smdi.paa new file mode 100644 index 0000000000..0c43002132 Binary files /dev/null and b/addons/apl/data/m3tripod_smdi.paa differ diff --git a/addons/apl/data/mortarBaseplate.rvmat b/addons/apl/data/mortarBaseplate.rvmat new file mode 100644 index 0000000000..13739500c6 --- /dev/null +++ b/addons/apl/data/mortarBaseplate.rvmat @@ -0,0 +1,95 @@ +ambient[]={1,1,1,1.000000}; +diffuse[]={1,1,1,1.000000}; +forcedDiffuse[]={0.000000,0.000000,0.000000,0.000000}; +emmisive[]={0.000000,0.000000,0.000000,1.000000}; +specular[]={1,1,1,1.000000}; +specularPower=40.000000; +PixelShaderID="super"; +VertexShaderID="super"; +class Stage1 +{ + texture="z\ace\addons\apl\data\mortarBaseplate_nohq.paa"; + uvSource="tex"; + class uvTransform + { + aside[]={1.000000,0.000000,0.000000}; + up[]={0.000000,1.000000,0.000000}; + dir[]={0.000000,0.000000,0.000000}; + pos[]={0.000000,0.000000,0.000000}; + }; +}; +class Stage2 +{ + texture="a3\weapons_f\Data\DetailMaps\metal_detail_dt.paa"; + uvSource="tex"; + class uvTransform + { + aside[]={8.0000,0.000000,0.000000}; + up[]={0.000000,8.0000,0.000000}; + dir[]={0.000000,0.000000,0.000000}; + pos[]={0.000000,0.000000,0.000000}; + }; +}; +class Stage3 +{ + texture="#(argb,8,8,3)color(0,0,0,0,MC)"; + uvSource="tex"; + class uvTransform + { + aside[]={1.000000,0.000000,0.000000}; + up[]={0.000000,1.000000,0.000000}; + dir[]={0.000000,0.000000,0.000000}; + pos[]={0.000000,0.000000,0.000000}; + }; +}; +class Stage4 +{ + texture="z\ace\addons\apl\data\mortarBaseplate_as.paa"; + uvSource="tex"; + class uvTransform + { + aside[]={1.000000,0.000000,0.000000}; + up[]={0.000000,1.000000,0.000000}; + dir[]={0.000000,0.000000,0.000000}; + pos[]={0.000000,0.000000,0.000000}; + }; +}; +class Stage5 +{ + texture="z\ace\addons\apl\data\mortarBaseplate_smdi.paa"; + uvSource="tex"; + class uvTransform + { + aside[]={1.000000,0.000000,0.000000}; + up[]={0.000000,1.000000,0.000000}; + dir[]={0.000000,0.000000,0.000000}; + pos[]={0.000000,0.000000,0.000000}; + }; +}; +class Stage6 +{ + texture = "#(ai,32,128,1)fresnel(3.38,5.33)"; + uvSource="tex"; + class uvTransform + { + aside[]={1.000000,0.000000,0.000000}; + up[]={0.000000,1.000000,0.000000}; + dir[]={0.000000,0.000000,0.000000}; + pos[]={0.000000,0.000000,0.000000}; + }; +}; +class Stage7 +{ + texture="a3\data_f\env_land_co.paa"; + uvSource="tex"; + class uvTransform + { + aside[]={1.000000,0.000000,0.000000}; + up[]={0.000000,1.000000,0.000000}; + dir[]={0.000000,0.000000,0.000000}; + pos[]={0.000000,0.000000,0.000000}; + }; +}; +class StageTI { + texture = "a3\data_f\default_vehicle_ti_ca.paa"; +}; diff --git a/addons/apl/data/mortarBaseplate_as.paa b/addons/apl/data/mortarBaseplate_as.paa new file mode 100644 index 0000000000..7cafb83c0d Binary files /dev/null and b/addons/apl/data/mortarBaseplate_as.paa differ diff --git a/addons/apl/data/mortarBaseplate_co.paa b/addons/apl/data/mortarBaseplate_co.paa new file mode 100644 index 0000000000..3dfe27f12c Binary files /dev/null and b/addons/apl/data/mortarBaseplate_co.paa differ diff --git a/addons/apl/data/mortarBaseplate_nohq.paa b/addons/apl/data/mortarBaseplate_nohq.paa new file mode 100644 index 0000000000..f177b8d5c2 Binary files /dev/null and b/addons/apl/data/mortarBaseplate_nohq.paa differ diff --git a/addons/apl/data/mortarBaseplate_smdi.paa b/addons/apl/data/mortarBaseplate_smdi.paa new file mode 100644 index 0000000000..9b71d965ec Binary files /dev/null and b/addons/apl/data/mortarBaseplate_smdi.paa differ diff --git a/addons/apl/data/static.rvmat b/addons/apl/data/static.rvmat new file mode 100644 index 0000000000..88c9f8e629 --- /dev/null +++ b/addons/apl/data/static.rvmat @@ -0,0 +1,98 @@ +#define _ARMA_ + +class StageTI +{ + texture = "a3\weapons_f\ammoboxes\bags\data\backpacks_ti_ca.paa"; +}; +ambient[] = {1.0,1.0,1.0,1.0}; +diffuse[] = {1.0,1.0,1.0,1.0}; +forcedDiffuse[] = {0.0,0.0,0.0,0.0}; +emmisive[] = {0.0,0.0,0.0,1.0}; +specular[] = {0.0,0.0,0.0,1.0}; +specularPower = 0.0; +PixelShaderID = "Super"; +VertexShaderID = "Super"; +class Stage1 +{ + texture = "z\ace\addons\apl\data\static_nohq.paa"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; +class Stage2 +{ + texture = "#(argb,8,8,3)color(0.5,0.5,0.5,1,DT)"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; +class Stage3 +{ + texture = "#(argb,8,8,3)color(0,0,0,0,MC)"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; +class Stage4 +{ + texture = "#(argb,8,8,3)color(1,1,1,1,AS)"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; +class Stage5 +{ + texture = "#(argb,8,8,3)color(0,0,1,1,SMDI)"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; +class Stage6 +{ + texture = "#(ai,32,128,1)fresnel(1.58,0.71)"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; +class Stage7 +{ + texture = "a3\data\env2_co.paa"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; diff --git a/addons/apl/data/static_co.paa b/addons/apl/data/static_co.paa new file mode 100644 index 0000000000..4130790f24 Binary files /dev/null and b/addons/apl/data/static_co.paa differ diff --git a/addons/apl/data/static_nohq.paa b/addons/apl/data/static_nohq.paa new file mode 100644 index 0000000000..5d22d896f3 Binary files /dev/null and b/addons/apl/data/static_nohq.paa differ diff --git a/addons/arsenal/functions/fnc_onLoadoutsClose.sqf b/addons/arsenal/functions/fnc_onLoadoutsClose.sqf index 1b25ad4945..07af50139d 100644 --- a/addons/arsenal/functions/fnc_onLoadoutsClose.sqf +++ b/addons/arsenal/functions/fnc_onLoadoutsClose.sqf @@ -18,8 +18,6 @@ GVAR(currentLoadoutsTab) = nil; private _arsenalDisplay = findDisplay IDD_ace_arsenal; private _mouseBlockCtrl = _arsenalDisplay displayCtrl IDC_mouseBlock; -GVAR(cameraPosition) = GVAR(previousCameraPos); -GVAR(previousCameraPos) = nil; GVAR(loadoutsSearchbarFocus) = nil; GVAR(loadoutsPanelFocus) = nil; diff --git a/addons/arsenal/functions/fnc_onLoadoutsOpen.sqf b/addons/arsenal/functions/fnc_onLoadoutsOpen.sqf index d22124359d..eb72087f89 100644 --- a/addons/arsenal/functions/fnc_onLoadoutsOpen.sqf +++ b/addons/arsenal/functions/fnc_onLoadoutsOpen.sqf @@ -30,9 +30,6 @@ GVAR(currentLoadoutsTab) = -1; GVAR(loadoutsSearchbarFocus) = false; GVAR(loadoutsPanelFocus) = false; -GVAR(previousCameraPos) = GVAR(cameraPosition); -GVAR(cameraPosition) = [5,0,20,[-0.85,0,0.85]]; - private _panelContentCtrl = _display displayCtrl IDC_contentPanel; _panelContentCtrl ctrlSetFontHeight (4.5 * GRID_H); _panelContentCtrl ctrlCommit 0; diff --git a/addons/arsenal/functions/fnc_statBarStatement_accuracy.sqf b/addons/arsenal/functions/fnc_statBarStatement_accuracy.sqf index fa8ff55c35..1cd3f149c3 100644 --- a/addons/arsenal/functions/fnc_statBarStatement_accuracy.sqf +++ b/addons/arsenal/functions/fnc_statBarStatement_accuracy.sqf @@ -18,18 +18,19 @@ params ["_stat", "_config", "_args"]; _args params ["_statMinMax", "_barLimits"]; -TRACE_4("statBarStatement_accuracy",_stat,_config,_statMinMax,_barLimits); private _fireModes = getArray (_config >> "modes"); private _dispersion = []; { - private _n = log (getNumber (_config >> _x >> "dispersion")); - if (!finite _n) then {_n = 0;}; - _dispersion pushBackUnique _n; + if (getNumber (_config >> _x >> "showToPlayer") != 0) then { + private _n = log (getNumber (_config >> _x >> "dispersion")); + + if (!finite _n) then {_n = 0;}; + _dispersion pushBackUnique _n; + }; } foreach _fireModes; _dispersion sort true; -TRACE_1("",_dispersion); linearConversion [_statMinMax select 0, _statMinMax select 1, _dispersion param [0, 0], _barLimits select 0, _barLimits select 1] diff --git a/addons/arsenal/stringtable.xml b/addons/arsenal/stringtable.xml index a3bd8baa04..adcb26ee59 100644 --- a/addons/arsenal/stringtable.xml +++ b/addons/arsenal/stringtable.xml @@ -6,11 +6,13 @@ Cacher Verstecken Ukryj - 非表示 + 隠す Nascondere 숨김 隱藏 隐藏 + Спрятать + Ocultar Hide interface @@ -22,6 +24,8 @@ 인터페이스 숨기기 隱藏介面 隐藏介面 + Скрыть интерфейс + Oculta a Interface Loadouts @@ -33,28 +37,34 @@ 로드아웃 裝備 装备 + Комплекты + Loadouts Export Exporter Exportieren Eksportuj - 出力 + エクスポート Esporta 내보내기 匯出 汇出 + Экспорт + Exportar Import Importer Importieren Importuj - 取込 + インポート Importa 가져오기 匯入 汇入 + Импорт + Importar Close @@ -66,17 +76,21 @@ 닫기 關閉 关闭 + Закрыть + Fechar No virtual item available Aucun objet virtuel disponible Kein virtuelles Objekt verfügbar Brak dostępnych przedmiotów wirtualnych - 利用可能なバーチャル アイテムは無し + 利用可能なバーチャル アイテムはありません Nessun oggetto virtuale disponibile 가상장비 사용 불가 沒有可用的虛擬物品 没有可用的虚拟物品 + Виртуальный предмет недоступен + Nenhum item virtual disponível Save @@ -88,6 +102,8 @@ 저장 保存 保存 + Сохранить + Salvar Save the current loadout @@ -99,11 +115,15 @@ 현재 로드아웃 저장 保存當前的裝備 保存当前的装备 + Сохранить текущий комплект экипировки + Salva o loadout atual [Shift+Click to save to mission defaults] [Shift + クリック] でミッション標準として保存します Shift + Klik aby zapisac jako domyślne dla misji + [Shift+Клик, чтобы сохранить в настройках по умолчанию] + [Shift+Clique para salvar nos padrões da missão] Rename @@ -115,6 +135,8 @@ 이름바꾸기 重新命名 重新命名 + Переименовать + Renomear Rename the selected loadout @@ -126,6 +148,8 @@ 선택한 로드아웃의 이름 바꾸기 重新命名當前選擇的裝備 重新命名当前选择的装备 + Переименовать выбранный комплект экипировки + Renomeia o loadout selecionado Load @@ -137,6 +161,8 @@ 불러오기 載入 载入 + Загрузить + Carregar Load the selected loadout @@ -148,6 +174,8 @@ 선택한 로드아웃 불러오기 載入當前選擇的裝備 载入当前选择的装备 + Загрузить выбранный комплект экипировки + Carrega o loadout selecionado Delete @@ -159,6 +187,8 @@ 삭제 刪除 删除 + Удалить + Apagar Delete the selected loadout @@ -170,6 +200,8 @@ 선택한 로드아웃 삭제하기 刪除當前選擇的裝備 删除当前选择的装备 + Удалить выбранный комплект экипировки + Apaga o loadout selecionado My loadouts @@ -181,6 +213,8 @@ 내 로드아웃 我的裝備 我的装备 + Мои комплекты + Meus loadouts Loadouts saved in your profile @@ -192,6 +226,8 @@ 프로필에 저장된 로드아웃 裝備已保存到你的設定檔中 装备已保存到你的设定档中 + Комплекты экипировки, сохраненные в вашем профиле + Loadouts salvos em seu perfil Default loadouts @@ -203,6 +239,8 @@ 기본 로드아웃 預設裝備 预设装备 + По умолчанию + Loadouts padrões Loadouts made available by the mission maker @@ -214,6 +252,8 @@ 미션메이커가 허용한 로드아웃 任務作者提供的預設裝備 任务作者提供的预设装备 + Комплекты экипировки, предоставляемые создателем миссии + Loadouts definidos pelo criador da missão Public loadouts @@ -225,6 +265,8 @@ 공용 로드아웃 公用裝備 公用装备 + Публичные комплекты + Loadouts públicos Loadouts shared by you and other players @@ -236,6 +278,8 @@ 플레이어들이 공유하는 로드아웃 由你與其他玩家分享的裝備配置 由你与其他玩家分享的装备配置 + Комплекты экипировки, опубликованные вами и другими игроками + Loadouts compartilhados por você ou outros jogadores Sort by weight @@ -247,6 +291,8 @@ 무게로 정렬 以重量排序 以重量排序 + Сортировка по весу + Ordenar por peso Sort by amount @@ -258,6 +304,8 @@ 갯수로 정렬 以數量排序 以数量排序 + Сортировка по количеству + Ordenar por quantidade Share or stop sharing the selected loadout @@ -269,6 +317,8 @@ 선택한 로드아웃 공유 혹은 공유중지 開始/停止分享當前選擇的裝備 开始/停止分享当前选择的装备 + Открыть или закрыть общий доступ к комплекту экипировки + Compartilhar ou parar de compartilhar o loadout selecionado Private @@ -280,6 +330,8 @@ 개인 私用 私用 + Приватный + Privado Public @@ -291,6 +343,8 @@ 공용 公用 公用 + Публичный + Público The default loadouts list is empty! @@ -302,17 +356,21 @@ 기본 로드아웃 목록이 비어있습니다! 沒有預設的裝備清單! 没有预设的装备清单! + Список комплекта экипировки пуст! + A lista de loadouts padrões está vazia! Default loadouts list exported to clipboard Liste d'équipements de base 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 클립보드에 기본 로드아웃 목록 내보내기 預設的裝備清單已匯出到剪貼簿中 预设的装备清单已汇出到剪贴簿中 + Список комплекта экипировки по умолчанию экспортирован в буфер + A lista de loadouts padrões foi exportada pra área de transferência Current loadout exported to clipboard @@ -324,6 +382,8 @@ 현재 로드아웃을 클립보드로 내보냈습니다. 當前的裝備已匯出到剪貼簿中 当前的装备已汇出到剪贴簿中 + Текущий список комплекта экипировки экспортирован в буфер + Loadout atual foi exportado pra área de transferência Wrong format provided @@ -335,28 +395,34 @@ 잘못된 형식 입력됨 提供的格式錯誤 提供的格式错误 + Неверный формат импорта + Format incorreto fornecido Default loadouts list imported from clipboard Liste d'équipements de base 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 클립보드에서 기본 로드아웃 가져오기 預設的裝備清單已從剪貼簿中匯入 预设的装备清单已从剪贴簿中汇入 + Список комплекта экипировки по умолчанию импортирован из буфера + A lista de loadouts padrões foi importada da área de transferência Loadout imported from clipboard Équipement importé depuis le presse papier Ausrüstung aus der Zwischenablage importiert Zestaw został importowany ze schowka - 装備はクリップボードから取込されました + 装備はクリップボードからインポートされました Equipaggiamento importato dagli appunti 클립보드에서 로드아웃을 가져왔습니다. 裝備已從剪貼簿中匯入 装备已从剪贴簿中汇入 + Список комплекта экипировки импортирован из буфера + Loadout importado da área de transferência The following loadout was deleted: @@ -368,6 +434,8 @@ 다음 로드아웃이 삭제됨 : 以下的裝備已被刪除: 以下的装备已被删除: + Удален комплект экипировки: + O seguinte loadout foi apagado: The following loadout is not public anymore: @@ -379,17 +447,21 @@ 다음 로드아웃이 더이상 공용이 아님: 以下的裝備已不再被分享: 以下的装备已不再被分享: + Этот комплект экипировки больше не публичный: + O seguinte loadout não é mais público: The name field is empty! Le champ nom est vide ! Das Feld "Name" ist leer! Pole nazwy jest puste! - 名前欄が空白です! + 名前が空白です! Il campo del nome è vuoto! 이름칸이 비었습니다! 名稱欄位為空! 名称栏位为空! + Поле имени пустое! + O nome não pode estar vazio! You are the author of this loadout @@ -401,6 +473,8 @@ 이 로드아웃의 제작자입니다. 你是這個裝備的作者 你是这个装备的作者 + Вы автор этого комплекта экипировки + Você é o autor desse loadout A loadout of yours with the same name is public @@ -412,6 +486,8 @@ 같은 이름의 로드아웃이 공용에 있습니다. 已有相同名稱的裝備在公用分享區 已有相同名称的装备在公用分享区 + Ваш комплект экипировки с таким же именем является публичным + Um loadout seu com o mesmo nome é público The following loadout was saved: @@ -423,6 +499,8 @@ 다음 로드아웃이 저장됨: 以下的裝備已被保存: 以下的装备已被保存: + Сохранен комплект экипировки: + O seguinte loadout foi salvo: The following loadout was loaded: @@ -434,6 +512,8 @@ 다음 로드아웃을 불러옴: 以下的裝備已被載入: 以下的装备已被载入: + Загружен комплект экипировки: + O seguinte loadout foi carregado: A loadout with the same name already exist! @@ -445,17 +525,21 @@ 같은 이름의 로드아웃이 이미 존재합니다! 已有相同名稱的裝備! 已有相同名称的装备! + Комплект с таким именем уже существует! + Um loadout com o mesmo nome já existe! was renamed to fut renommé en wurde umbenannt in zmienił nazwę na - 次の名前に改名されました + 次の名前に変更されました E' stato rinominato in 이름이 다음과 같이 변경됨: 已被改名為 已被改名为 + был переименован в + foi renameado para Invert camera controls @@ -467,6 +551,8 @@ 카메라 조종 반전 反轉攝影機控制 反转摄影机控制 + Инвертировать управление камерой + Inverter controles da câmera Enable mod icons @@ -478,6 +564,8 @@ 모드 아이콘 허가 啟用模組圖示 启用模组图示 + Включить иконки модов + Ativar ícones de mods Panel font height @@ -489,6 +577,8 @@ 패널 폰트 높이 面板字體高度 面板字体高度 + Размер шрифта панели + Altura da fonte do painel Allow default loadouts @@ -500,6 +590,8 @@ 기본 로드아웃 허용 允許預設裝備 允许预设装备 + Разрешить комплекты по умолчанию + Permitir loadouts padrões Allow loadout sharing @@ -511,6 +603,8 @@ 로드아웃 공유 허용 允許分享裝備 允许分享装备 + Разрешить публикацию комплектов + Permitir compartilhar loadouts Log missing / unavailable items @@ -522,6 +616,8 @@ 누락 된 항목 / 사용 할 수 없는 항목 기록 記錄遺失/無法使用的項目 记录遗失/无法使用的项目 + Вести журнал недоступных предметов + Registrar em log itens indisponíveis/não encontrados Primary magazine @@ -533,6 +629,8 @@ Primärmagazin 主要武器彈匣 主要武器弹匣 + Основной магазин + Carregador Primário Secondary magazine @@ -544,6 +642,8 @@ Sekundärmagazin 次要武器彈匣 次要武器弹匣 + Вторичный магазин + Carregador Secundário ACE Arsenal @@ -555,6 +655,8 @@ ACE 아스날 ACE虛擬軍火庫 ACE虚拟军火库 + ACE Арсенал + ACE Arsenal Allow the use of the default loadouts tab @@ -566,6 +668,8 @@ Erlaube die Nutzung des Standardausrüstungsreiters 允許使用預設的裝備 允许使用预设的装备 + Разрешить использование вкладки комплектов экипировки по умолчанию + Permite o uso da aba de loadouts padrões Show / hide mod icons for the left panel @@ -577,6 +681,8 @@ Zeigt/Versteckt Mod-Symbole in der linken Leiste 在左面板中顯示/隱藏模組圖示 在左面板中显示/隐藏模组图示 + Показать / скрыть значки модов в левой панели + Mostra / Esconde os ícones de mods no painel esquerdo Change the font height for text in the left / right panels @@ -588,6 +694,8 @@ Ändert die Schriftgröße für die linke/rechte Leiste 變更左/右面板中的字體高度 变更左/右面板中的字体高度 + Изменить размер шрифта для текста в левой / правой панелях + Muda o tamanho da fonte para os textos nos painéis esquerdo e direito Log missing / unavailable items in the RPT @@ -599,6 +707,8 @@ Fehlende Gegenstände werden in der RPT aufgezeichnet 記錄遺失/無法使用的項目到RPT檔案中 记录遗失/无法使用的项目到RPT档案中 + Вести журнал отсутствующих / недоступных предметов в RPT + Registrar em log itens indisponíveis no RPT Unable to open ACE arsenal @@ -610,6 +720,8 @@ 無法開啟ACE虛擬軍火庫 无法开启ACE虚拟军火库 Nie można otworzyć arsenału ACE + Невозможно открыть ACE Арсенал + Não foi possível abrir o ACE Arsenal Import BI VA loadouts to ACE Arsenal @@ -621,6 +733,8 @@ 汇入BI原厂虚拟军火库的装备到ACE虚拟军火库中 Importa l'arsenale virtuale BI nell'arsenale ACE Importuj zestawy wyposażenia z wirtualnego arsenału BI do arsenału ACE + Импорт комплектов из Арсенала BI в Арсенал ACE + Importar loadouts do BIS Arsenal para o ACE Arsenal No player unit available! Place a unit and mark it as "Player". @@ -632,17 +746,21 @@ 没有可用的玩家单位!请摆放一个单位并设定成"玩家"。 Non ci sono giocatori! Poisziona una unità e impostala come "Giocatore". Brak dostępnych jednostek gracza! Postaw jednostkę i oznacz ją jako "Gracz". + Нет доступных игроков! Разместите юнит и отметьте его как «Игрок» + Nenhuma unidade de jogador disponível! Coloque uma unidade e marque como "Player". No loadouts to import. Aucun loadout à importer. Keine Ausrüstungen zum Importieren - 取り込みする装備がありません。 + インポートする装備がありません。 가져올 로드 아웃이 없습니다. 沒有裝備被匯入 没有装备被汇入。 Non ci sono equipaggiamenti da importare. Brak zestawów wyposażenia do zaimportowania. + Нет комплектов для импорта + Nenhum loadout para importar. ACE Arsenal @@ -653,6 +771,8 @@ ACE虚拟军火库 Arsenale ACE Arsenał ACE + ACE Арсенал + ACE Arsenal Return to ACE Arsenal. @@ -663,6 +783,8 @@ 返回到ACE虚拟军火库。 Torna all'arsenale ACE Wróć do arsenału ACE. + Вернуться в ACE Арсенал + Voltar para o ACE Arsenal Use ACE Arsenal to try out different weapons and equipment. @@ -673,6 +795,8 @@ 使用ACE虚拟军火库来尝试不同的武器与装备。 Usa l'arsenale ACE per provare armi ed equipaggiamenti vari. Skorzystaj z arsenału ACE by wypróbować broń i ekwipunek. + Используйте ACE Arsenal, чтобы опробовать различное оружие и снаряжение. + Use o ACE Arsenal para experimentar diferentes armas e equipamentos. Try weapons and equipment and create your own loadouts. @@ -683,33 +807,44 @@ 尝试不同的武器与装备来组合你个人的装备配置。 Prova armi ed equipaggiamenti e creai i tuoi equipaggiamenti personalizzati. Wypróbuj broń i ekwipunek i stwórz swoje własne zestawy wyposażenia. + Опробуйте оружие и снаряжение, создавайте собственные комплекты экипировки. + Experimente armas e equipamentos e crie seus próprios loadouts. Open the loadouts screen + Öffnet das Ausrüstungsmenü Affiche la page des équipements 開啟裝備選單 开启装备选单 装備画面を開く Apri la pagina degli equipaggiamenti Otwórz ekran zestawów + Открыть окно комплектов экипировки + Abre a tela de loadouts Export current / default loadouts + Exportiert aktuelles / standard Loadout Exporte l'équipement actuel ou la liste d'équipements de base 匯出當前/預設的裝備 汇出当前/预设的装备 - 現在 / 標準装備を出力 + 現在/標準装備をエクスポートします Esporta l'equipaggiamento attuale oppure la lista degli equipaggiamenti di base Eksportuj obecne / domyślne zestawy wyposażenia + Экспорт комплектов экипировки + Exporta loadout atual / loadouts padrões Import current / default loadouts + Importiert aktuelles / standard Loadout Importer l'équipement actuel ou la liste d'équipements de base 匯入當前/預設的裝備 汇入当前/预设的装备 - 現在 / 標準装備を取込 + 現在/標準装備をインポートします Importa l'equipaggiamento attuale oppure la lista degli equipaggiamenti di base Importuj obecne / domyślne zestawy wyposażenia + Импорт комплектов экипировки + Importa loadout atual / loadouts padrões Potassium levels @@ -719,6 +854,8 @@ 鉀水平 Ilvello di potassio Poziomy potasu + Уровень Калия + Níveis de Potássio Magnification @@ -730,7 +867,7 @@ Увеличение Vergrößerung Zvětšení - Aumentox + Aumento 배율 放大倍数 拡大倍率 @@ -739,9 +876,11 @@ Nightvision Support Nachtsicht Unterstützung - 暗視装置に対応 + 暗視装置への対応有無 Wsparcie noktowizyjne Supporto visore notturno + Поддержка ночного видения + Suporte de Visão Noturna Primary supported @@ -749,6 +888,8 @@ プライマリが対応 Wspierane przez broń główną Primario supportato + Поддерживается осн. прицелом + Primária suportada Secondary supported @@ -756,6 +897,8 @@ セカンダリが対応 Wspierane przez broń drugorzędną Secondario supportato + Поддерживается доп. прицелом + Secundária suportada Primary integrated @@ -763,6 +906,8 @@ プライマリに内蔵 Zintegrowane z bronią główną Primario integrato + Интегрирован в осн. прицел + Primária integrada Not Supported @@ -770,42 +915,56 @@ セカンダリに内蔵 Nie wspierane Non supportato + Не поддерживается + Não suportado Page + Seite Page ページ 页面 頁面 Pagina Strona + Стр. + Página Enable the faces / voices / insignias tabs + Aktiviere die Gesichter-, Stimmen- und Abzeichenübersicht Activer les onglets faces / voix / insignes 顔 / 声 / 記章タブを有効化 启用脸谱/声音/徽章/选项 啟用臉譜/聲音/徽章選項 Abilita volti, voci e insegne Aktywuj zakładki twarz / głos / insygnia + Включить вкладки Лиц / Голосов / Знаков различия + Ativar as abas de rostos / vozes / insígnias Empty the selected container + Aktuellen Container leeren Vider le conteneur selectionné 選択されたコンテナは空です 选择的箱子是空的 清空選擇的箱子 Svuota il contenitore selezionato Opróżnij wybrany pojemnik + Очистить контейнер + Esvaziar o cointâiner selecionado Exported class name to clipboard + Der Klassenname wurde in die Zwischenablage exportiert Nom de classe exporté dans le presse papier - クリップボードへクラスネームを出力 + クリップボードへクラスネームをエクスポート 将种类复制到剪贴板 輸出 class name 到剪貼簿上 Copiato il nome della classe negli appunti Wyeksportowano nazwę klasy do schowka + Имя класса, экспортированного в буфер + O nome da classe foi exportado para a área de transferência Mode @@ -829,7 +988,7 @@ Lista blanca Whitelist Seznam povolených - Lista branca + Lista Branca Liste blanche Fehérlista Вайтлист @@ -841,9 +1000,12 @@ Blacklist + Blacklist 禁止リスト Lista Nera Czarna lista (lista wykluczeń) + Чёрный список + Lista Negra Items @@ -863,28 +1025,46 @@ Export current items list as an array for use in 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 + Экспорт текущего списка предметов в виде массива для использования в скриптах Import items list array from clipboard (should be the same format as export) + Importiert alles aus der Zwischenablage (Sollte im gleichen Format sein, wie beim Exportieren) Zaimportuj listę przedmiotów ze schowka (lista musi być w tym samym formacie jak przy exporcie) + クリップボードからアイテムリストをアレイでインポートします (エクスポートと同じフォーマットである必要があります) + Импорт массива списка предметов из буфера (должен иметь тот же формат, что при экспорте) + Importar lista de itens da área de transferência (deve estar no mesmo formato que uma lista exportada) Add Compatible Items + Füge kompatible Gegenstände hinzu Dodaj kompatybilne przedmioty + 対応アイテムを追加 + Добавить совместимые предметы + Adicionar itens compatíveis Will automatically add compatible attachments or magazines (based on selected category) for all weapons in current items list + 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 Time to live + Lebenszeit Durée de vie - 生存時間 + 有効時間 Czas by żyć Scadenza (TTL) + Время действия + Time to live diff --git a/addons/atragmx/functions/fnc_initGunList.sqf b/addons/atragmx/functions/fnc_initGunList.sqf index 3ffcaf976c..8714357985 100644 --- a/addons/atragmx/functions/fnc_initGunList.sqf +++ b/addons/atragmx/functions/fnc_initGunList.sqf @@ -63,7 +63,7 @@ if (_resetGunList) then { ["7.62x51mm M993" , 912, 100, 0.0803840, -0.00109390, 7.62, 0, 2, 10, 120, 0, 0, 8.230, 7.82, 25.40, 0.359, 1, "ICAO", [[-15,893],[0,900],[10,907],[15,912],[25,926],[30,935],[35,946]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], ["7.62x51mm Subsonic", 314, 100, 0.3344490, -0.00060194, 6.86, 0, 2, 10, 120, 0, 0, 12.96, 7.82, 25.40, 0.502, 1, "ICAO", [[-15,312],[0,313],[10,314],[15,314],[25,316],[30,317],[35,318]] , [[0, 0.303], [250, 0.409], [320, 0.427], [420, 0.445], [550, 0.460], [650, 0.467], [730, 0.470]], true], - ["7.62x39mm" , 708, 100, 0.1066160, -0.00154815, 7.62, 0, 2, 10, 120, 0, 0, 7.970, 7.82, 25.40, 0.275, 1, "ICAO", [[-15,689],[0,696],[10,703],[15,708],[25,722],[30,731],[35,742]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], + ["7.62x39mm" , 715, 100, 0.104782, -0.00154815, 7.62, 0, 2, 10, 120, 0, 0, 7.970, 7.92, 24.00, 0.275, 1, "ICAO", [[-15,696],[0,703],[10,710],[15,715],[25,729],[30,738],[35,749]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], ["6.5x39mm" , 766, 100, 0.0872025, -0.00077363, 6.35, 0, 2, 10, 120, 0, 0, 7.970, 6.71, 22.86, 0.524, 1, "ICAO", [[-15,747],[0,754],[10,761],[15,766],[25,780],[30,789],[35,800]] , [[0, 0.525], [910, 0.520], [1050, 0.515], [1270, 0.506], [1390, 0.503], [1570, 0.500], [1770, 0.498]], true], ["6.5x47mm Lapua" , 767, 100, 0.0868248, -0.00069003, 6.35, 0, 2, 10, 120, 0, 0, 9.007, 6.71, 22.86, 0.577, 1, "ICAO", [[-15,748],[0,755],[10,762],[15,767],[25,781],[30,790],[35,801]] , [[0, 0.578], [970, 0.574], [1140, 0.569], [1430, 0.557], [1610, 0.553], [1750, 0.551], [1860, 0.550]], true], @@ -76,7 +76,7 @@ if (_resetGunList) then { ["5.56x45mm Mk318" , 872, 100, 0.0814490, -0.00125880, 7.11, 0, 2, 10, 120, 0, 0, 4.018, 5.70, 17.78, 0.307, 1, "ASM" , [[-15,853],[0,860],[10,867],[15,872],[25,886],[30,895],[35,906]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], ["5.56x45mm M995" , 861, 100, 0.0825279, -0.00126182, 7.11, 0, 2, 10, 120, 0, 0, 4.536, 5.70, 17.78, 0.310, 1, "ASM" , [[-15,842],[0,849],[10,856],[15,861],[25,875],[30,884],[35,895]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], - ["5.45x39mm 7N6M" , 727, 100, 0.0802286, -0.00119458, 3.81, 0, 2, 10, 120, 0, 0, 3.428, 5.59, 16.00, 0.336, 1, "ICAO", [[-15,708],[0,715],[10,722],[15,727],[25,741],[30,750],[35,761]], [[0, 0.339], [730, 0.331], [960, 0.323], [1100, 0.321], [1220, 0.320], [1380, 0.320], [1480, 0.320]], true]]; + ["5.45x39mm 7N6M" , 735, 100, 0.0784916, -0.00119458, 3.81, 0, 2, 10, 120, 0, 0, 3.43, 5.6, 16.00, 0.336, 1, "ICAO", [[-15,716],[0,723],[10,730],[15,735],[25,749],[30,758],[35,769]], [[0, 0.339], [730, 0.331], [960, 0.323], [1100, 0.321], [1220, 0.320], [1380, 0.320], [1480, 0.320]], true]]; [] call FUNC(clear_user_data); profileNamespace setVariable ["ACE_ATragMX_gunList", GVAR(gunList)]; diff --git a/addons/attach/stringtable.xml b/addons/attach/stringtable.xml index 252f25e4ed..8e0768e1fe 100644 --- a/addons/attach/stringtable.xml +++ b/addons/attach/stringtable.xml @@ -40,7 +40,7 @@ Odczep przedmiot Détacher l'objet Odepnout předmět - Separar item + Desprender item Stacca l'oggetto Tárgy lecsatolása Отсоединить @@ -200,7 +200,7 @@ Umieść Placer Položit - Colocar + Fixar Posiziona Elhelyez Установить diff --git a/addons/ballistics/CfgAmmo.hpp b/addons/ballistics/CfgAmmo.hpp index 0fe41a517a..ef38336f3e 100644 --- a/addons/ballistics/CfgAmmo.hpp +++ b/addons/ballistics/CfgAmmo.hpp @@ -67,18 +67,18 @@ class CfgAmmo { class ACE_B_556x45_Ball_Tracer_Dim: B_556x45_Ball_Tracer_Red { nvgOnly = 1; }; - class B_545x39_Ball_F : BulletBase { - airFriction=-0.00119458; - ACE_caliber=5.588; - ACE_bulletLength=21.59; - ACE_bulletMass=3.42792; - ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19}; - ACE_ballisticCoefficients[]={0.168}; - ACE_velocityBoundaries[]={}; - ACE_standardAtmosphere="ICAO"; - ACE_dragModel=7; - ACE_muzzleVelocities[]={735, 883, 892}; - ACE_barrelLengths[]={206.5, 414.02, 508.0}; + class B_545x39_Ball_F: BulletBase { + airFriction = -0.001195; + ACE_caliber = 5.6; // https://bobp.cip-bobp.org/uploads/tdcc/tab-i/5-45-x-39-en.pdf + ACE_bulletLength = 21.59; + ACE_bulletMass = 3.43; + ACE_ammoTempMuzzleVelocityShifts[] = {-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19}; + ACE_ballisticCoefficients[] = {0.168}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ICAO"; + ACE_dragModel = 7; + ACE_muzzleVelocities[] = {743, 848, 891, 900}; // at 21°C, at 15°C {735, 840, 883, 892} according with the AKS initSpeed + ACE_barrelLengths[] = {210, 314, 415, 508.0}; // respectively {AKS74U / AK105,AK12K / AK74 / default} }; class B_56x15_dual: BulletBase { tracerScale = 0.5; @@ -337,18 +337,18 @@ class CfgAmmo { ACE_muzzleVelocities[]={735, 770, 809, 838}; ACE_barrelLengths[]={406.4, 508.0, 604.5, 736.6}; }; - class B_762x39_Ball_F : BulletBase { - airFriction=-0.00154815; - ACE_caliber=7.823; - ACE_bulletLength=28.956; - ACE_bulletMass=7.9704; - ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19}; - ACE_ballisticCoefficients[]={0.275}; - ACE_velocityBoundaries[]={}; - ACE_standardAtmosphere="ICAO"; - ACE_dragModel=1; - ACE_muzzleVelocities[]={650, 716, 750}; - ACE_barrelLengths[]={254.0, 414.02, 508.0}; + class B_762x39_Ball_F: BulletBase { + airFriction = -0.001548; + ACE_caliber = 7.92; // https://bobp.cip-bobp.org/uploads/tdcc/tab-i/7-62-x-39-en.pdf + ACE_bulletLength = 28.956; + ACE_bulletMass = 7.97; + ACE_ammoTempMuzzleVelocityShifts[] = {-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19}; + ACE_ballisticCoefficients[] = {0.275}; + ACE_velocityBoundaries[] = {}; + ACE_standardAtmosphere = "ICAO"; + ACE_dragModel = 1; + ACE_muzzleVelocities[] = {658, 678, 723, 743, 753}; // at 21°C, at 15°C {650, 670, 715, 735, 745} according with the AKM,AK12,AK12U,RPK initSpeed + ACE_barrelLengths[] = {254, 314, 415, 520, 590}; // respectively {default / AK104,AK15K / AK47,AKM,AK103,AK15 / SKS / RPK} }; class B_9x21_Ball : BulletBase { airFriction=-0.00211064; @@ -604,15 +604,17 @@ class CfgAmmo { ACE_barrelLengths[]={304.8, 406.4, 609.6}; }; class B_570x28_Ball: BulletBase { - ACE_caliber = 5.7; + ACE_caliber = 5.7; // https://bobp.cip-bobp.org/uploads/tdcc/tab-i/tabical-en-page7.pdf ACE_bulletLength = 21.6; // http://blog.thejustnation.org/2011/04/5-7x28mm-ammo-review/ ACE_bulletMass = 2; // based on the SS190 - ACE_ballisticCoefficients[] = {0.177}; //http://m.delphiforums.com/autogun/messages/5267/7 + ACE_ammoTempMuzzleVelocityShifts[] = {-2.655, -2.547, -2.285, -2.012, -1.698, -1.280, -0.764, -0.153, 0.596, 1.517, 2.619}; + ACE_ballisticCoefficients[] = {0.084}; // https://www.thefirearmblog.com/blog/2016/10/24/modern-personal-defense-weapon-calibers-4-6x30mm-hk/ ACE_velocityBoundaries[] = {}; - ACE_standardAtmosphere = "ASM"; // 50/50 chance to get it right + ACE_standardAtmosphere = "ICAO"; ACE_dragModel = 7; - ACE_muzzleVelocities[] = {716,776}; - ACE_barrelLengths[] = {264,407}; + ACE_muzzleVelocities[] = {716, 776}; // at 21°C, 715-775 m/s at 15°C according with the 50Rnd_570x28_SMG_03 initSpeed + ACE_barrelLengths[] = {264, 407}; + airFriction = -0.002619; // default BI value -0.001412 }; class B_19mm_HE: BulletBase { tracerScale = 1; diff --git a/addons/ballistics/CfgMagazines.hpp b/addons/ballistics/CfgMagazines.hpp index a89cf7022d..b57b17c1fc 100644 --- a/addons/ballistics/CfgMagazines.hpp +++ b/addons/ballistics/CfgMagazines.hpp @@ -58,7 +58,7 @@ class CfgMagazines { }; class 30Rnd_545x39_Mag_F: CA_Magazine { - initSpeed = 735; + initSpeed = 735; // default BI value according with the ACE_muzzleVelocities at 15°C }; class 30Rnd_556x45_Stanag: CA_Magazine { @@ -120,7 +120,7 @@ class CfgMagazines { }; class 30Rnd_762x39_Mag_F: CA_Magazine { - initSpeed = 716; + initSpeed = 715; // default BI value according with the ACE_muzzleVelocities at 15°C }; class 20Rnd_762x51_Mag: CA_Magazine { diff --git a/addons/ballistics/CfgWeapons.hpp b/addons/ballistics/CfgWeapons.hpp index e81e6bbc85..9413884b51 100644 --- a/addons/ballistics/CfgWeapons.hpp +++ b/addons/ballistics/CfgWeapons.hpp @@ -75,6 +75,7 @@ class CfgWeapons { ACE_barrelTwist = 228.6; // 1:9 inch twist ACE_barrelLength = 407; ACE_twistDirection = 1; + initSpeed = -1.083916; // 775 m/s according with the ACE_muzzleVelocities at 15°C, default BI value -1.1 (786 m/s) modes[] = {"Single"}; }; class SMG_03C_BASE: SMG_03_TR_BASE { @@ -142,6 +143,9 @@ class CfgWeapons { // M14 class DMR_06_base_F: Rifle_Long_Base_F { + ACE_barrelLength = 558.8; + ACE_barrelTwist = 304.8; + initSpeed = -0.999395; class Single: Mode_SemiAuto { dispersion = MOA_TO_RAD(0.81); }; @@ -151,6 +155,12 @@ class CfgWeapons { }; }; + class DMR_06_hunter_base_F: DMR_06_base_F { + class Single: Single { + dispersion = MOA_TO_RAD(0.81); + }; + }; + // MX LSW class arifle_MX_SW_F: arifle_MX_Base_F { magazines[] = { @@ -260,11 +270,6 @@ class CfgWeapons { // Stoner 99 LMG class LMG_Mk200_F: Rifle_Long_Base_F { - magazines[] = { - "200Rnd_65x39_cased_Box", - "200Rnd_65x39_cased_Box_Tracer", - "ACE_200Rnd_65x39_cased_Box_Tracer_Dim" - }; initSpeed = -0.999327; ACE_barrelTwist = 177.8; ACE_barrelLength = 317.5; @@ -355,23 +360,47 @@ class CfgWeapons { // AKS class arifle_AKS_base_F: Rifle_Base_F { - initSpeed = -1.0; - ACE_barrelTwist = 160.02; - ACE_barrelLength = 206.5; + initSpeed = -1; // 735 m/s according with the ACE_muzzleVelocities at 15°C + ACE_barrelTwist = 160; + ACE_barrelLength = 210; }; // AKM class arifle_AKM_base_F: Rifle_Base_F { - initSpeed = -1.0; - ACE_barrelTwist = 199.898; - ACE_barrelLength = 414.02; + initSpeed = -1; // 715 m/s according with the ACE_muzzleVelocities at 15°C + ACE_barrelTwist = 240; + ACE_barrelLength = 415; }; - // AK12 + // AK15,AK15K,RPK (AK12) class arifle_AK12_base_F: Rifle_Base_F { - initSpeed = -1.0; - ACE_barrelTwist = 199.898; - ACE_barrelLength = 414.02; + initSpeed = -1; // 715 m/s according with the ACE_muzzleVelocities at 15°C + ACE_barrelTwist = 240; + ACE_barrelLength = 415; + }; + + class arifle_AK12U_base_F: arifle_AK12_base_F { + initSpeed = -0.937063; // 715*0.937063= 670 m/s according with the ACE_muzzleVelocities at 15°C + ACE_barrelTwist = 240; + ACE_barrelLength = 314; + }; + + class arifle_RPK12_base_F: arifle_AK12_base_F { + initSpeed = -1.041958; // 715*1.041958= 745 m/s according with the ACE_muzzleVelocities at 15°C + ACE_barrelTwist = 240; + ACE_barrelLength = 590; + }; + + // MSBS GROT (Promet) + class arifle_MSBS65_base_F: Rifle_Base_F { + initSpeed = -0.971576; // 774*0.971576= 752 m/s according with the ACE_muzzleVelocities at 15°C + ACE_barrelTwist = 228.6; + ACE_barrelLength = 406.4; // 16" + }; + + class arifle_MSBS65_Mark_base_F: arifle_MSBS65_base_F { + initSpeed = -1.007752; // 774*1.007752= 780 m/s according with the ACE_muzzleVelocities at 15°C + ACE_barrelLength = 508; // 20" }; // QBZ-95-1 @@ -789,23 +818,6 @@ class CfgWeapons { ACE_barrelLength = 620.014; }; - // M14 - class srifle_DMR_06_camo_F: DMR_06_base_F { - magazines[] = { - "20Rnd_762x51_Mag", - "ACE_20Rnd_762x51_Mag_Tracer", - "ACE_20Rnd_762x51_Mag_Tracer_Dim", - "ACE_20Rnd_762x51_Mk316_Mod_0_Mag", - "ACE_20Rnd_762x51_M118LR_Mag", - "ACE_20Rnd_762x51_Mk319_Mod_0_Mag", - "ACE_20Rnd_762x51_M993_AP_Mag", - "ACE_20Rnd_762x51_Mag_SD" - }; - initSpeed = -0.999395; - ACE_barrelTwist = 304.8; - ACE_barrelLength = 558.8; - }; - // HK121 class MMG_01_hex_F: MMG_01_base_F { initSpeed = -0.985613; diff --git a/addons/ballistics/stringtable.xml b/addons/ballistics/stringtable.xml index bbd6e4ddd9..a413386d1e 100644 --- a/addons/ballistics/stringtable.xml +++ b/addons/ballistics/stringtable.xml @@ -2283,47 +2283,62 @@ Barrel twist + Dralllänge 銃身の転度 膛线缠距 膛線扭度 Rigatura della canna Gwintowanie lufy + Нарезы ствола + Barrel Twist Barrel length + Lauflänge Longueur du canon 銃身長 身管长度 槍管長度 Lunghezza della canna Długość lufy + Длина ствола + Comprimento do cano Ballistic coefficient + Ballistischer Koeffizient Coefficient ballistique 弾道係数 弹道系数 彈道係數 Coefficente balistico Współczynnik balistyczny + Баллистический коэффициент + Coeficiente balístico Bullet mass + Projektilgewicht Masse d'une balle 弾丸重量 弹头重量 彈頭重量 Massa del proiettile Masa pocisku + Масса пули + Massa do projétil Muzzle velocity + Mündungsgeschwindigkeit Vitesse à la bouche 銃口初速 枪口初速 槍口初速 Velocità iniziale Prędkość wylotowa + Начальная скорость + Velocidade de Saída diff --git a/addons/captives/functions/fnc_addLoadCaptiveActions.sqf b/addons/captives/functions/fnc_addLoadCaptiveActions.sqf index 81710f161d..d1ad8f603d 100644 --- a/addons/captives/functions/fnc_addLoadCaptiveActions.sqf +++ b/addons/captives/functions/fnc_addLoadCaptiveActions.sqf @@ -10,7 +10,7 @@ * Child actions * * Example: - * [kevin] call ace_medical_fnc_addLoadCaptiveActions + * [kevin] call ace_captives_fnc_addLoadCaptiveActions * * Public: No */ diff --git a/addons/captives/stringtable.xml b/addons/captives/stringtable.xml index 5683d9b5f4..a8c8350db8 100644 --- a/addons/captives/stringtable.xml +++ b/addons/captives/stringtable.xml @@ -10,6 +10,8 @@ 捕虜 포로설정 Jeńcy + Пленные + Prisioneiros Take Prisoner @@ -21,7 +23,7 @@ Arresta il prigioniero Tomar Prisioneiro Foglyul ejtés - Взять в плен + Арестовать 捕虜にする 포박하기 逮捕俘虜 @@ -37,7 +39,7 @@ Libera il prigioniero Libertar Prisioneiro Fogoly szabadon engedése - Освободить пленника + Освободить пленного 捕虜を解放する 풀어주기 釋放俘虜 @@ -53,7 +55,7 @@ Scorta il Prigioniero Escoltar Prisioneiro Fogoly kísérése - Конвоировать пленника + Конвоировать пленного 捕虜を移動させる 포로 호송하기 護送俘虜 @@ -85,7 +87,7 @@ Prima devi arrestarlo! Você deve tomá-lo como prisioneiro primeiro! Először foglyul kell ejtened őt! - Вы должны сначала взять его в плен! + Вы должны сначала арестовать его! 捕虜を取っている必要があります! 먼저 포로로 만들어야합니다! 你必須先逮捕他! @@ -149,7 +151,7 @@ A algema plástica permite que você contenha prisioneiros. Fascetta per arrestare i prigionieri Gyorskötöző, emberek foglyulejtéséhez használható. - Кабельные стяжки позволяют связывать пленников. + Кабельные стяжки используются для связывания рук при аресте ケーブル タイは捕虜を制圧できます。 케이블 타이는 포로를 구류시킬때 씁니다. 束線帶可以綁住俘虜 @@ -179,7 +181,7 @@ Parar de se render Přestat se vzdávat Podejmij walkę ponownie - Прекратить сдачу в плен + Прекратить сдаваться Megadás abbahagyása Smetti di arrenderti 投降をやめる @@ -212,7 +214,7 @@ Sincroniza uma unidade para fazer com que ela se renda. Synchronise une unité pour la rendre captive. Egység szinkronizálása, hogy kapituláljon. - Синхронизируйте с юнитами, чтобы заставить их сдаться в плен. + Синхронизируйте с юнитами, чтобы заставить их сдаться. Sincronizza una unità per farla arrendere. 同期されたユニットを投降させます。 투항시키기 위해 동기화합니다. @@ -224,7 +226,7 @@ Einheit in Handschellen legen Skuj jednostkę Fazer unidade algemada - Связать юнита + Связать юниту руки Spoutat jednotku Metti manette all'unità Hacer que la unidad esté esposada @@ -239,7 +241,7 @@ Synchronisiere eine Einheit, um sie in Handschellen zu legen. Zsynchronizuj z jednostką, aby została skuta. Sincronizar uma unidade para deixá-la algemada. - Синхронизируйте с юнитами, чтобы сделать их связанными. + Синхронизируйте с юнитами, чтобы связать им руки. Synchronizovat s jednotkou, která má být v poutech. Sincronizza un'unità per metterle le manette. Sincroniza una unidad para hacer que esté esposada. @@ -274,7 +276,7 @@ Controla as configurações de rendição e abraçadeiras Contrôle les paramètres de la reddition et des Serflex Szabályozza a kapituláció és bilincselés beállításait - Управляет настройками сдачи в плен и связывания + Управляет настройками ареста и сдачи в плен Controlla le impostazioni per la resa e le manette 投降したユニットや拘束されたユニットの扱いを設定します。 투항과 케이블 타이에 관련한 설정 @@ -290,7 +292,7 @@ Pode algemar o próprio lado Peut capturer sa propre faction Saját oldal megbilincselhető - Связать союзника + Можно связывать руки союзникам Puoi ammanettare unità alleate 拘束ユニットを自陣営へ 자기편을 포박 할 수 있습니다. @@ -306,7 +308,7 @@ Os jogadores podem algemar unidades do seu lado Les joueurs peuvent utiliser les Serflex sur 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 プレイヤーが拘束したユニットの陣営を自陣営に変更させます。 자기편에게 케이블타이를 사용할 수 있게합니다 @@ -319,10 +321,10 @@ Permitir rendición Povolit vzdávání Kapitulation erlauben - Permite rendição + Permitir Rendição Permettre la reddition Kapituláció engedélyezése - Сдаться в плен + Разрешить сдаваться Permetti Resa 投降を許可 투항 활성화 @@ -338,7 +340,7 @@ Jogadores podem se render depois de guardar sua arma Les joueurs peuvent se rendre après avoir rangé leur arme 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 プレイヤーは武器を収めたあと投降できるようにします。 비무장한 플레이어가 투항할 수 있게 합니다 @@ -350,7 +352,7 @@ Benötigt Kapitulation Wymagaj kapitulacji Requer rendição - Требовать пленения + Требовать сдаться для ареста Requiere rendición Vzdávání vyžadováno Richiedi Resa @@ -365,7 +367,7 @@ Spieler müssen sich erst ergeben, bevor sie gefangen genommen werden können Wymagaj od graczy kapitulacji zanim będzie można ich zaaresztować Requer que jogadores se rendam antes de poderem ser presos - Требуется, чтобы игрок сдался в плен прежде, чем его можно будет связать + Требовать для ареста, чтобы игроки вначале сдавались Requiere que los Jugadores se rindan antes de arrestarlos Vyžaduje, aby se hráč nejdříve vzdal, poté může být spoután I giocatori devono arrendersi prima che possano essere arrestati @@ -380,7 +382,7 @@ Nur Ergeben Tylko kapitulacja Somente rendição - Только сдавшийся в плен + Только сдавшийся Solo rendición Pouze vzdávání Solo Resa @@ -414,6 +416,8 @@ 设置在游标下的单位成俘虏状态。 커서의 병력을 포박합니다. Ustawia jednostkę pod kursorem jako jeniec. + Арестовывает указанный курсором юнит + Torna a unidade sob o cursor um prisioneiro Require AI surrendering @@ -424,6 +428,8 @@ 需要AI先行投降 AI 항복 필요 Wymaga poddania się przez SI + Требовать ИИ сдаться для ареста + Requer rendição da IA Require AI to surrender before they can be arrested @@ -434,6 +440,8 @@ 在逮捕AI之前该AI必须先进入投降状态。 포박하기 전에 먼저 AI가 투항해야만 합니다. Wymaga poddania się przez SI zanim aresztowanie będzie możliwe + Требовать для ареста, чтобы ИИ вначале сдавались + Requer que a IA se renda antes que seja presa diff --git a/addons/cargo/CfgVehicles.hpp b/addons/cargo/CfgVehicles.hpp index d3a800040e..ab41cac4db 100644 --- a/addons/cargo/CfgVehicles.hpp +++ b/addons/cargo/CfgVehicles.hpp @@ -63,6 +63,11 @@ class CfgVehicles { GVAR(space) = 4; GVAR(hasCargo) = 1; }; + class Tank_F: Tank {}; + class UGV_02_Base_F: Tank_F { + GVAR(space) = 0; + GVAR(hasCargo) = 0; + }; class Car_F; class Truck_F: Car_F { diff --git a/addons/cargo/XEH_preInit.sqf b/addons/cargo/XEH_preInit.sqf index 3d7ac380c2..1b0894b77e 100644 --- a/addons/cargo/XEH_preInit.sqf +++ b/addons/cargo/XEH_preInit.sqf @@ -11,5 +11,6 @@ PREP_RECOMPILE_END; GVAR(initializedItemClasses) = []; GVAR(initializedVehicleClasses) = []; GVAR(cargoHolderTypes) = ["Car", "Air", "Tank", "Ship", "Cargo_base_F", "Land_PaperBox_closed_F"]; +GVAR(disableParadropEffectsClasstypes) = ["Car_F"]; ADDON = true; diff --git a/addons/cargo/functions/fnc_paradropItem.sqf b/addons/cargo/functions/fnc_paradropItem.sqf index 2f9ae06336..4c873d189e 100644 --- a/addons/cargo/functions/fnc_paradropItem.sqf +++ b/addons/cargo/functions/fnc_paradropItem.sqf @@ -69,8 +69,10 @@ _itemObject setVelocity ((velocity _vehicle) vectorAdd ((vectorNormalized (vecto _item attachTo [_parachute, [0,0,1]]; _parachute setVelocity _velocity; - private _light = "Chemlight_yellow" createVehicle [0,0,0]; - _light attachTo [_item, [0,0,0]]; + if ((GVAR(disableParadropEffectsClasstypes) findIf {_item isKindOf _x}) == -1) then { + private _light = "Chemlight_yellow" createVehicle [0,0,0]; + _light attachTo [_item, [0,0,0]]; + }; }, [_itemObject], 0.7] call CBA_fnc_waitAndExecute; @@ -83,8 +85,10 @@ _itemObject setVelocity ((velocity _vehicle) vectorAdd ((vectorNormalized (vecto }; if (getPos _item select 2 < 1) then { - private _smoke = "SmokeshellYellow" createVehicle [0,0,0]; - _smoke attachTo [_item, [0,0,0]]; + if ((GVAR(disableParadropEffectsClasstypes) findIf {_item isKindOf _x}) == -1) then { + private _smoke = "SmokeshellYellow" createVehicle [0,0,0]; + _smoke attachTo [_item, [0,0,0]]; + }; [_this select 1] call CBA_fnc_removePerFrameHandler; }; diff --git a/addons/cargo/stringtable.xml b/addons/cargo/stringtable.xml index 86e0106a93..d3fa5dfe7c 100644 --- a/addons/cargo/stringtable.xml +++ b/addons/cargo/stringtable.xml @@ -237,6 +237,8 @@ 货物空间 Przestrzeń ładunkowa 화물 공간 + Грузовое пространство + Espaço de Carga The cargo space available in this vehicle/container @@ -247,6 +249,8 @@ 设定此载具/集装箱可装载多少货物 Dostępna przestrzeń ładunkowa w tym pojeździe/kontenerze 이 차량/컨테이너에서 사용가능한 화물 공간 + Грузовое пространство, доступное в этом транспортном средстве / контейнере + O espaço de carga disponível nesse veículo/contâiner Cargo Size @@ -257,6 +261,8 @@ 货物的大小 Wielkość ładunku 화물 크기 + Размер груза + Tamanho da Carga The cargo space required to hold this object (-1 for unloadable) @@ -267,6 +273,8 @@ 此货物会占掉多少空间(设定-1的话此货物就不能被装载) Wymagana przestrzeń ładunkowa dla tego obiektu (-1 dla niemożliwych do załadowania) 이 화물을 적재하는데 필요한 공간 (-1=무조건 적재가능) + Грузовое пространство, необходимое для размещения этого объекта (-1 для незагружаемого) + O Espaço de carga necessário para carregar esse objeto (-1 para que não seja carregável) Airdrop @@ -278,6 +286,8 @@ Lancio Aereo 空投 空投 + Десантирование груза + Lançamento Aéreo Unlevel Flight @@ -289,6 +299,8 @@ Volo non Livellato 此架飛機並無保持水平飛行 此架飞机并无保持水平飞行 + Неподходящее положение + Desnivelar Vôo Paradrop Time Coefficient @@ -300,6 +312,8 @@ 空投时间系数 Współczynnik czasu zrzutu 공중 투하 시간 계수 + Коэффициент времени десантирования + Fator de Tempo para soltar a carga Modifier for how long it takes to paradrop a cargo item. @@ -311,18 +325,26 @@ 设定空投所需消耗的时间. Modyfikator wskazujący jak dużo czasu potrzeba by zrzucić przedmiot na spadochronie. 화물을 공중 투하 하는데 얼마나 걸리는 시간 설정 + Модификатор времени, необходимого для десантирования груза + Coeficiente de quanto tempo leva para soltar uma carga de paraquedas Load Time Coefficient + Ladezeitmultiplikator 積載時間の係数 Współczynnik czasu załadowania Coefficente Tempo Caricamento + Коэффициент времени погрузки + Fator de tempo para carregar 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アイテムの大きさにこの値が乗法され、時間 (秒) を変更できます。 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 Время (сек) - это размер предмета, умноженный на это значение. + Coeficiente de quanto tempo leva para carregar/descarregar itens.\nTempo, em segundos, é o tamanho do objeto multiplicado por esse valor. diff --git a/addons/chemlights/stringtable.xml b/addons/chemlights/stringtable.xml index 4fc7cc4e8b..10a67f3386 100644 --- a/addons/chemlights/stringtable.xml +++ b/addons/chemlights/stringtable.xml @@ -11,6 +11,8 @@ Luce chimica 螢光棒 萤光棒 + Химсвет + Bastões de Luz Prepare %1 @@ -22,6 +24,8 @@ Prepara %1 使用%1 使用%1 + Приготовить %1 + Preparar %1 %1<br/>Prepared @@ -33,6 +37,8 @@ %1 <br/> Preparata %1<br/>已使用 %1<br/>已使用 + %1<br/>Приготовлен + %1<br/>Preparado No inventory space @@ -60,6 +66,8 @@ [ACE] Luci chimiche [ACE] 螢光棒 [ACE] 萤光棒 + [ACE] Химсвет + [ACE] Bastões de Luz Chemlight (Orange) @@ -71,6 +79,8 @@ Luce chimica (Arancione) 螢光棒 (橘色) 萤光棒 (橘色) + Химсвет (Оранжевый) + Bastão de Luz (Laranja) Orange Light @@ -82,6 +92,8 @@ Luce Arancione 橘色光 橘色光 + Оранжевый свет + Luz Laranja Type: Light - Orange<br />Rounds: 1<br />Used in: Hand @@ -93,6 +105,8 @@ Tipo: Luce - Arancione<br/>Rimanenti: 1<br/>Usata in: Mano 類型: 光 - 橘色<br />發數: 1<br />使用於: 手 类型: 光 - 橘色<br />发数: 1<br />使用于: 手 + Тип: Свет - Оранжевый<br />1 штука<br />В руках + Tipo: Luz - Laranja<br/>Usos: 1<br/>Usado em: Mão Chemlight (White) @@ -104,6 +118,8 @@ Luce chimica (Bianca) 螢光棒 (白色) 萤光棒 (白色) + Химсвет (Белый) + Bastão de Luz (Branco) White Light @@ -115,6 +131,8 @@ Luce Bianca 白色光 白色光 + Белый свет + Luz Branca Type: Light - White<br />Rounds: 1<br />Used in: Hand @@ -126,6 +144,8 @@ Tipo: Luce - Bianca<br/>Rimanenti: 1<br/>Usata in: Mano 類型: 光 - 白色<br />發數: 1<br />使用於: 手 类型: 光 - 白色<br />发数: 1<br />使用于: 手 + Тип: Свет - Белый<br />1 штука<br />В руках + Tipo: Luz - Branco<br/>Usos: 1<br/>Usado em: Mão Chemlight (Hi Red) @@ -137,6 +157,8 @@ Luce chimica (Hi Rossa) 螢光棒 (超亮紅色) 萤光棒 (超亮红色) + Химсвет (Ярко-Красный) + Bastão de Luz (Vermelho Forte) Red Hi Light @@ -148,6 +170,8 @@ Luce Hi Rossa 超亮紅色光 超亮红色光 + Яркий Красный свет + Luz forte vermelha Type: Light - Red Hi (30 minute)<br />Rounds: 1<br />Used in: Hand @@ -159,6 +183,8 @@ Tipo: Luce - Rossa Hi (30 minuti)<br />Rimanenti: 1<br/>Usata in: Mano 類型: 光 - 超亮紅色 (30分鐘)<br />發數: 1<br />使用於: 手 类型: 光 - 超亮红色 (30分钟)<br />发数: 1<br />使用于: 手 + Тип: Свет - Ярко-Красный (30 минут)<br />1 штука<br />В руках + Tipo: Luz - Vermelho Forte (30 minutos)<br/>Usos: 1<br/>Usado em: Mão Chemlight (Hi Yellow) @@ -170,6 +196,8 @@ Luce chimica (Hi Gialla) 螢光棒 (超亮黃色) 萤光棒 (超亮黄色) + Химсвет (Ярко-Желтый) + Bastão de Luz (Amarelo Forte) Yellow Hi Light @@ -181,6 +209,8 @@ Luce Hi Gialla 超亮黃色光 超亮黄色光 + Яркий Желтый свет + Luz forte amarela Type: Light - Yellow Hi (30 minute)<br />Rounds: 1<br />Used in: Hand @@ -192,6 +222,8 @@ Tipo: Luce - Gialla Hi (30 minuti)<br />Rimanenti: 1<br/>Usata in: Mano 類型: 光 - 超亮黃色 (30分鐘)<br />發數: 1<br />使用於: 手 类型: 光 - 超亮黄色 (30分钟)<br />发数: 1<br />使用于: 手 + Тип: Свет - Ярко-Желтый (30 минут)<br />1 штука<br />В руках + Tipo: Luz - Amarelo Forte (30 minutos)<br/>Usos: 1<br/>Usado em: Mão Chemlight (Hi White) @@ -203,6 +235,8 @@ Luce chimica (Hi Bianca) 螢光棒 (超亮白色) 萤光棒 (超亮白色) + Химсвет (Ярко-Белый) + Bastão de Luz (Branco Forte) White Hi Light @@ -214,6 +248,8 @@ Luce Hi Bianca 超亮白色光 超亮白色光 + Яркий Белый свет + Luz forte branca Type: Light - White Hi (30 minute)<br />Rounds: 1<br />Used in: Hand @@ -225,69 +261,98 @@ Tipo: Luce - Bianca Hi (30 minuti)<br />Rimanenti: 1<br/>Usata in: Mano 類型: 光 - 超亮白色 (30分鐘)<br />發數: 1<br />使用於: 手 类型: 光 - 超亮白色 (30分钟)<br />发数: 1<br />使用于: 手 + Тип: Свет - Ярко-Белый (30 минут)<br />1 штука<br />В руках + Tipo: Luz - Branco Forte (30 minutos)<br/>Usos: 1<br/>Usado em: Mão Chemlight (Hi Blue) Cyalume (Hi Bleu) ケミライト (高輝度 青) Świetlik (jaskrawy niebieski) + Knicklicht (Blau, Hell) Luce chimica (Hi Blu) + Химсвет (Ярко-Синий) + Bastão de Luz (Azul Forte) Blue Hi Light Lum. bleue haute intensité + Helles, blaues Knicklicht 高輝度の青色 Jaskrawe niebieskie światło Luce Hi Blu + Яркий Синий свет + Luz forte azul Type: Light - Blue Hi (30 minute)<br />Rounds: 1<br />Used in: Hand Type: Lumière - bleue Hi (30 minutes)<br />Nbre: 1<br /> À main + Typ: Licht - blau, hell (30 Minuten)<br />Anzahl: 1<br />Benutzt in: Hand 種類: 照明 - 高輝度 青 (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 + Тип: Свет - Ярко-Синий (30 минут)<br />1 штука<br />В руках + Tipo: Luz - Azul Forte (30 minutos)<br/>Usos: 1<br/>Usado em: Mão Chemlight (Hi Green) Cyalume (Hi Vert) + Knicklicht (Grün, Hell) ケミライト (高輝度 緑) Świetlik (jaskrawy zielony) Luce chimica (Hi Verde) + Химсвет (Ярко-Зеленый) + Bastão de Luz (Verde Forte) Green Hi Light Lum. verte haute intensité + Helles, grünes Knicklicht 高輝度の青色 Jaskrawe zielone światło Luce Hi Verde + Яркий Зеленый свет + Luz forte verde Type: Light - Green Hi (30 minute)<br />Rounds: 1<br />Used in: Hand Type: Lumière - verte Hi (30 minutes)<br />Nbre: 1<br /> À main + Typ: Licht - grün, hell (30 Minuten)<br />Anzahl: 1<br />Benutzt in: Hand 種類: 照明 - 高輝度 緑 (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 + Тип: Свет - Ярко-Зеленый (30 минут)<br />1 штука<br />В руках + Tipo: Luz - Verde Forte (30 minutos)<br/>Usos: 1<br/>Usado em: Mão Chemlight (Ultra-Hi Orange) Cyalume (Ultra-Hi orange) + Knicklicht (Orange, Hell) ケミライト (高輝度 オレンジ) Świetlik (ultra-jaskrawy pomarańczowy) Luce chimica (Ultra-Hi Arancione) + Химсвет (Ультраяркий Оранжевый) + Bastão de Luz (Laranja Ultra Forte) Orange Ultra-Hi Light Lum. orange ultra haute intensité + Helles, orangenes Knicklicht ウルトラ高輝度のオレンジ色 Ultra-jaskrawe pomarańczowe światło Luce Ultra-Hi Arancione + Ультраяркий Оранжевый свет + Luz ultra forte laranja Type: Light - Orange Ultra-Hi (5 minute)<br />Rounds: 1<br />Used in: Hand Type: Lumière - Orange Ultra-Hi (5 minutes)<br />Nbre: 1<br /> À main + Typ: Licht - orange, hell (30 Minuten)<br />Anzahl: 1<br />Benutzt in: Hand 種類: 照明 - ウルトラ高輝度 オレンジ (5分間)<br />装填数: 1<br />次で使用: 携帯 Typ: Światło - ultra-jaskrawe pomarańczowe (30 minut)<br/>Pociski: 1<br/>Używany w: ręce Tipo: Luce - Ultra-Hi (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 Chemlight (IR) @@ -299,6 +364,8 @@ Luce chimica (IR) 螢光棒 (紅外線) 萤光棒 (红外线) + Химсвет (Инфракрасный) + Bastão de Luz (IV) IR Light @@ -310,6 +377,8 @@ Luce IR 紅外線光 红外线光 + Инфракрасный свет + Bastão de luz infravermelho Type: Light - Infrared<br />Rounds: 1<br />Used in: Hand @@ -321,6 +390,8 @@ Tipo: Luce - Infrarossi<br />Usata in: Mano 類型: 光 - 紅外線<br />發數: 1<br />使用於: 手 类型: 光 - 红外线<br />发数: 1<br />使用于: 手 + Тип: Свет - Инфракрасный<br />1 штука<br />В руках + Tipo: Luz - Infravermelho<br/>Usos: 1<br/>Usado em: Mão Chemlight Shield (Empty) @@ -332,6 +403,8 @@ Scudo Luce chimica (Vuoto) 螢光棒保護殼 (空) 萤光棒保护壳 (空) + Контейнер для Химсвета (Пуст) + Estojo de Luz (Vazio) Shield for chemlights. Combine with chemlight to prepare reading light. @@ -343,6 +416,8 @@ Scudo per luci chimiche. Combina con una luce chimica per una luce da lettura. 螢光棒的保護殼. 與螢光棒結合後可充當閱讀燈 萤光棒的保护壳. 与萤光棒结合后可充当阅读灯. + Защитный контейнер для Химсвета. Объедините с Химсветом, чтобы подготовить Свет для чтения + Estojo para os bastões de luz. Combine com o bastão de luz para preparar luz de leitura. Chemlight Shield (Green) @@ -354,6 +429,8 @@ Scudo Luce Chimica (Verde) 螢光棒保護殼 (綠色) 萤光棒保护壳 (绿色) + Контейнер для Химсвета (Зел) + Estojo de Luz (Verde) Green reading light. @@ -365,6 +442,8 @@ Luce da lettura Verde. 綠色閱讀燈 绿色阅读灯。 + Ночник из Химсвета (Зеленый) + Luz de leitura verde. Chemlight Shield (Red) @@ -376,6 +455,8 @@ Scudo Luce Chimica (Rossa) 螢光棒保護殼 (紅色) 萤光棒保护壳 (红色) + Контейнер для Химсвета (Красн) + Estojo de Luz (Vermelho) Red reading light. @@ -387,6 +468,8 @@ Luce da lettura Rossa. 紅色閱讀燈 红色阅读灯。 + Ночник из Химсвета (Красный) + Luz de leitura vermelha. Chemlight Shield (Blue) @@ -398,6 +481,8 @@ Scudo Luce Chimica (Blu) 螢光棒保護殼 (藍色) 萤光棒保护壳 (蓝色) + Контейнер для Химсвета (Син) + Estojo de Luz (Azul) Blue reading light. @@ -409,6 +494,8 @@ Luce da lettura Blu. 藍色閱讀燈 蓝色阅读灯。 + Ночник из Химсвета (Синий) + Luz de leitura azul. Chemlight Shield (Yellow) @@ -420,6 +507,8 @@ Scudo Luce Chimica (Gialla) 螢光棒保護殼 (黃色) 萤光棒保护壳 (黄色) + Контейнер для Химсвета (Желт) + Estojo de Luz (Amarelo) Yellow reading light. @@ -431,6 +520,8 @@ Luce da lettura Gialla. 黃色閱讀燈 黄色阅读灯。 + Ночник из Химсвета (Желтый) + Luz de leitura amarela. Chemlight Shield (Orange) @@ -442,6 +533,8 @@ Scudo Luce Chimica (Arancione) 螢光棒保護殼 (橘色) 萤光棒保护壳 (橘色) + Контейнер для Химсвета (Оранж) + Estojo de Luz (Laranja) Orange reading light. @@ -453,6 +546,8 @@ Luce da lettura Arancione. 橘色閱讀燈 橘色阅读灯。 + Ночник из Химсвета (Оранжевый) + Luz de leitura laranja. Chemlight Shield (White) @@ -464,6 +559,8 @@ Scudo Luce Chimica (Bianca) 螢光棒保護殼 (白色) 萤光棒保护壳 (白色) + Контейнер для Химсвета (Белый) + Estojo de Luz (Branco) White reading light. @@ -475,6 +572,8 @@ Luce da lettura Bianca. 白色閱讀燈 白色阅读灯。 + Ночник из Химсвета (Белый) + Luz de leitura branca. diff --git a/addons/common/XEH_PREP.hpp b/addons/common/XEH_PREP.hpp index a331837fb2..3fbe081fae 100644 --- a/addons/common/XEH_PREP.hpp +++ b/addons/common/XEH_PREP.hpp @@ -138,6 +138,7 @@ PREP(positionToASL); PREP(progressBar); PREP(readSettingFromModule); PREP(receiveRequest); +PREP(registerItemReplacement); PREP(removeCanInteractWithCondition); PREP(removeSpecificMagazine); PREP(requestCallback); diff --git a/addons/common/XEH_postInit.sqf b/addons/common/XEH_postInit.sqf index 5efc75b8df..c65b674577 100644 --- a/addons/common/XEH_postInit.sqf +++ b/addons/common/XEH_postInit.sqf @@ -19,8 +19,8 @@ //Status Effect EHs: [QGVAR(setStatusEffect), {_this call FUNC(statusEffect_set)}] call CBA_fnc_addEventHandler; -["forceWalk", false, ["ACE_SwitchUnits", "ACE_Attach", "ACE_dragging", "ACE_Explosives", "ACE_Ladder", "ACE_Sandbag", "ACE_refuel", "ACE_rearm", "ACE_Trenches"]] call FUNC(statusEffect_addType); -["blockSprint", false, []] call FUNC(statusEffect_addType); +["forceWalk", false, ["ace_advanced_fatigue", "ACE_SwitchUnits", "ACE_Attach", "ACE_dragging", "ACE_Explosives", "ACE_Ladder", "ACE_Sandbag", "ACE_refuel", "ACE_rearm", "ACE_Trenches"]] call FUNC(statusEffect_addType); +["blockSprint", false, ["ace_advanced_fatigue", "ace_medical_fracture"]] call FUNC(statusEffect_addType); ["setCaptive", true, [QEGVAR(captives,Handcuffed), QEGVAR(captives,Surrendered)]] call FUNC(statusEffect_addType); ["blockDamage", false, ["fixCollision", "ACE_cargo"]] call FUNC(statusEffect_addType); ["blockEngine", false, ["ACE_Refuel"]] call FUNC(statusEffect_addType); @@ -121,8 +121,8 @@ if (isServer) then { [QGVAR(fixFloating), FUNC(fixFloating)] call CBA_fnc_addEventHandler; [QGVAR(fixPosition), FUNC(fixPosition)] call CBA_fnc_addEventHandler; -["ace_loadPersonEvent", FUNC(loadPersonLocal)] call CBA_fnc_addEventHandler; -["ace_unloadPersonEvent", FUNC(unloadPersonLocal)] call CBA_fnc_addEventHandler; +["ace_loadPersonEvent", LINKFUNC(loadPersonLocal)] call CBA_fnc_addEventHandler; +["ace_unloadPersonEvent", LINKFUNC(unloadPersonLocal)] call CBA_fnc_addEventHandler; [QGVAR(lockVehicle), { _this setVariable [QGVAR(lockStatus), locked _this]; @@ -145,9 +145,23 @@ if (isServer) then { [QGVAR(playActionNow), {(_this select 0) playActionNow (_this select 1)}] call CBA_fnc_addEventHandler; [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(setVanillaHitPointDamage), {(_this select 0) setHitPointDamage (_this select 1)}] call CBA_fnc_addEventHandler; [QGVAR(addWeaponItem), {(_this select 0) addWeaponItem [(_this select 1), (_this select 2)]}] call CBA_fnc_addEventHandler; +[QGVAR(setVanillaHitPointDamage), { + params ["_object", "_hitPointAnddamage"]; + private _damageDisabled = !isDamageAllowed _object; + + if (_damageDisabled) then { + _object allowDamage true; + }; + + _object setHitPointDamage _hitPointAnddamage; + + if (_damageDisabled) then { + _object allowDamage false; + }; +}] call CBA_fnc_addEventHandler; + // Request framework [QGVAR(requestCallback), FUNC(requestCallback)] call CBA_fnc_addEventHandler; [QGVAR(receiveRequest), FUNC(receiveRequest)] call CBA_fnc_addEventHandler; @@ -298,7 +312,7 @@ addMissionEventHandler ["PlayerViewChanged", { if (isNull player) exitWith {true}; private _UAV = getConnectedUAV player; if (!alive player) then {_UAV = objNull;}; - private _position = (UAVControl _UAV) param [1, ""]; + private _position = [player] call FUNC(getUavControlPosition); private _seatAI = objNull; private _turret = []; switch (toLower _position) do { diff --git a/addons/common/config.cpp b/addons/common/config.cpp index 44af1ee7ce..557b45b732 100644 --- a/addons/common/config.cpp +++ b/addons/common/config.cpp @@ -10,7 +10,7 @@ class CfgPatches { author = CSTRING(ACETeam); authors[] = {"KoffeinFlummi"}; url = ECSTRING(main,URL); - VERSION_CONFIG_COMMON; + VERSION_CONFIG; }; }; @@ -67,9 +67,7 @@ class ACE_Rsc_Control_Base { #include "CompassControl.hpp" #include "CfgUIGrids.hpp" -class ACE_Extensions { - extensions[] = {}; -}; +class ACE_Extensions {}; class ACE_Tests { vehicleTransportInventory = QPATHTOF(dev\test_vehicleInventory.sqf); diff --git a/addons/common/functions/fnc_arithmeticGetResult.sqf b/addons/common/functions/fnc_arithmeticGetResult.sqf index 418d510d66..ea5c2f3897 100644 --- a/addons/common/functions/fnc_arithmeticGetResult.sqf +++ b/addons/common/functions/fnc_arithmeticGetResult.sqf @@ -1,12 +1,12 @@ #include "script_component.hpp" /* * Author: PabstMirror - * Gets arithmetic result from a set. + * Returns the arithmetic result of performing the given operation on a set. * * Arguments: - * 0: Namespace + * 0: Namespace * 1: Number Set ID - * 2: Operation (sum, product, min, max, avg) + * 2: Operation (max, min, sum, product, avg) (Case Sensitive) * * Return Value: * Value @@ -18,51 +18,44 @@ * Public: Yes */ -params ["_namespace", "_setID", "_op"]; -TRACE_3("params",_namespace,_setID,_op); +params ["_namespace", "_setID", "_operation"]; +TRACE_3("arithmeticGetResult",_namespace,_setID,_operation); -private _data = (_namespace getVariable _setID) param [2, []]; +private _data = (_namespace getVariable _setID) param [2, [{0}]]; -switch (_op) do { - case ("sum"): { - private _result = 0; - { - _result = _result + (call _x); - nil - } count _data; - _result // return +switch (_operation) do { + case "max": { + selectMax (_data apply {call _x}) }; - case ("product"): { + case "min": { + selectMin (_data apply {call _x}) + }; + case "sum": { + private _result = 0; + + { + _result = _result + call _x; + } forEach _data; + + _result + }; + case "product": { private _result = 1; + { - _result = _result * (call _x); - nil - } count _data; - _result // return + _result = _result * call _x; + } forEach _data; + + _result }; - case ("min"): { - private _result = 1e99; - { - _result = _result min (call _x); - nil - } count _data; - _result // return - }; - case ("max"): { - private _result = -1e99; - { - _result = _result max (call _x); - nil - } count _data; - _result // return - }; - case ("avg"): { + case "avg": { private _result = 0; + { - _result = _result + (call _x); - nil - } count _data; - _result / (count _data); // return + _result = _result + call _x; + } forEach _data; + + _result / count _data }; default {3735928559}; }; diff --git a/addons/common/functions/fnc_arithmeticSetSource.sqf b/addons/common/functions/fnc_arithmeticSetSource.sqf index 0d7503aa90..ce24c408ef 100644 --- a/addons/common/functions/fnc_arithmeticSetSource.sqf +++ b/addons/common/functions/fnc_arithmeticSetSource.sqf @@ -4,7 +4,7 @@ * Adds or removes a source to an arithmetic set. * * Arguments: - * 0: Namespace + * 0: Namespace * 1: Number Set ID * 2: Source * 3: Code that returns a number (can access var _namespace) [use {} to remove] @@ -20,13 +20,15 @@ */ params ["_namespace", "_setID", "_source", "_variable"]; -TRACE_4("params",_namespace,_setID,_source,_variable); +TRACE_4("arithmeticSetSource",_namespace,_setID,_source,_variable); private _hash = _namespace getVariable _setID; + if (isNil "_hash") then { _hash = [] call CBA_fnc_hashCreate; _namespace setVariable [_setID, _hash]; }; + if (_variable isEqualTo {}) then { TRACE_1("removing",_source); [_hash, _source] call CBA_fnc_hashRem; diff --git a/addons/common/functions/fnc_cbaSettings.sqf b/addons/common/functions/fnc_cbaSettings.sqf index 4eb84d54da..273c72323e 100644 --- a/addons/common/functions/fnc_cbaSettings.sqf +++ b/addons/common/functions/fnc_cbaSettings.sqf @@ -21,6 +21,9 @@ LOG("Adding ACE_Settings to CBA_settings"); GVAR(cbaSettings_forcedSettings) = []; GVAR(cbaSettings_missionSettings) = []; GVAR(settings) = []; // will stay empty - for BWC? +#ifdef DEBUG_MODE_FULL +GVAR(settingsMovedToSQF) = []; +#endif // Add Event Handlers: [QGVAR(setSetting), { @@ -66,6 +69,13 @@ GVAR(settings) = []; // will stay empty - for BWC? false } count GVAR(runAtSettingsInitialized); GVAR(runAtSettingsInitialized) = nil; //cleanup + + #ifdef DEBUG_MODE_FULL + INFO_1("checking settingsMovedToSQF [%1]",count GVAR(settingsMovedToSQF)); + { + if (isNil _x) then { WARNING_1("setting [%1] NOT moved to sqf",_x); }; + } forEach GVAR(settingsMovedToSQF); + #endif }] call CBA_fnc_addEventHandler; private _start = diag_tickTime; @@ -81,6 +91,10 @@ for "_index" from 0 to (_countOptions - 1) do { } else { WARNING_1("Setting [%1] - Already defined from somewhere else??",_varName); }; + #ifdef DEBUG_MODE_FULL + } else { + GVAR(settingsMovedToSQF) pushBack configName _optionEntry; + #endif }; }; diff --git a/addons/common/functions/fnc_checkFiles.sqf b/addons/common/functions/fnc_checkFiles.sqf index dee144c40e..3d5adc101c 100644 --- a/addons/common/functions/fnc_checkFiles.sqf +++ b/addons/common/functions/fnc_checkFiles.sqf @@ -67,38 +67,43 @@ if (!(_oldCompats isEqualTo [])) then { }; /////////////// -// check dlls +// check extensions /////////////// -if (toLower (productVersion select 6) in ["linux", "osx"]) then { - INFO("Operating system does not support DLL file format"); +private _platform = toLower (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"); } else { { - private _versionEx = _x callExtension "version"; + private _extension = configName _x; + private _isWindows = _platform == "windows" && {getNumber (_x >> "windows") == 1}; + private _isLinux = _platform == "linux" && {getNumber (_x >> "linux") == 1}; + private _isClient = hasInterface && {getNumber (_x >> "client") == 1}; + private _isServer = !hasInterface && {getNumber (_x >> "server") == 1}; - if (_versionEx == "") then { - private _extension = ".dll"; + 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]; + }; - if (productVersion select 7 == "x64") then { - _extension = "_x64.dll"; + private _platformExt = [".dll", ".so"] select (_platform == "linux"); + _extensionFile = format ["%1%2", _extensionFile, _platformExt]; + + private _errorMsg = format ["Extension %1 not found.", _extensionFile]; + ERROR(_errorMsg); + + if (hasInterface) then { + ["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage); + }; + } else { + // Print the current extension version + INFO_2("Extension version: %1: %2",_extension,_versionEx); }; - - if (productVersion select 6 == "Linux") then { - _extension = ".so"; - }; - - private _errorMsg = format ["Extension %1%2 not found.", _x, _extension]; - - ERROR(_errorMsg); - - if (hasInterface) then { - ["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage); - }; - } else { - // Print the current extension version - INFO_2("Extension version: %1: %2",_x,_versionEx); }; - false - } count getArray (configFile >> "ACE_Extensions" >> "extensions"); + } forEach ("true" configClasses (configFile >> "ACE_Extensions")); }; /////////////// diff --git a/addons/common/functions/fnc_claim.sqf b/addons/common/functions/fnc_claim.sqf index 5c291c78da..3c30b8f28f 100644 --- a/addons/common/functions/fnc_claim.sqf +++ b/addons/common/functions/fnc_claim.sqf @@ -30,7 +30,7 @@ _target setVariable [QGVAR(owner), _unit, true]; // lock target object if (_lockTarget) then { - private _canBeDisassembled = !([] isEqualTo getArray (_target call CBA_fnc_getObjectConfig >> "assembleInfo" >> "dissasembleTo")); + private _canBeDisassembled = !([] isEqualTo getArray (_target call CBA_fnc_getObjectConfig >> "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 { diff --git a/addons/common/functions/fnc_disableUserInput.sqf b/addons/common/functions/fnc_disableUserInput.sqf index 44468641f3..c8a6bdc5aa 100644 --- a/addons/common/functions/fnc_disableUserInput.sqf +++ b/addons/common/functions/fnc_disableUserInput.sqf @@ -16,6 +16,7 @@ */ params ["_state"]; +TRACE_1("disableUserInput",_state); if (_state) then { disableSerialization; @@ -81,7 +82,7 @@ if (_state) then { openMap true; }; - if (isServer || {serverCommandAvailable "#kick"} || {player getVariable ["ACE_isUnconscious", false] && {(call FUNC(player)) getVariable [QEGVAR(medical,AllowChatWhileUnconscious), missionNamespace getVariable [QEGVAR(medical,AllowChatWhileUnconscious), false]]}}) then { + if (isServer || {serverCommandAvailable "#kick"}) then { if (!(_key in (actionKeys "DefaultAction" + actionKeys "Throw")) && {_key in (actionKeys "Chat" + actionKeys "PrevChannel" + actionKeys "NextChannel")}) then { _key = 0; }; diff --git a/addons/common/functions/fnc_isEOD.sqf b/addons/common/functions/fnc_isEOD.sqf index 226d315e36..303b258cb5 100644 --- a/addons/common/functions/fnc_isEOD.sqf +++ b/addons/common/functions/fnc_isEOD.sqf @@ -13,11 +13,11 @@ * is the unit an EOD * * Example: - * isSpecialist = [player] call FUNC(isEOD); + * [player] call ace_common_fnc_isEOD * * Public: Yes */ params ["_unit"]; -_unit getVariable ["ACE_isEOD", _unit getUnitTrait "explosiveSpecialist"] // return +(_unit getVariable ["ACE_isEOD", _unit getUnitTrait "explosiveSpecialist"]) in [1, true] diff --git a/addons/common/functions/fnc_loadPerson.sqf b/addons/common/functions/fnc_loadPerson.sqf index 466387cc72..a2d810444d 100644 --- a/addons/common/functions/fnc_loadPerson.sqf +++ b/addons/common/functions/fnc_loadPerson.sqf @@ -20,8 +20,9 @@ #define GROUP_SWITCH_ID QFUNC(loadPerson) params ["_caller", "_unit", ["_vehicle", objNull]]; +TRACE_3("loadPerson",_caller,_unit,_vehicle); -if (!([_caller, _unit, ["isNotDragging", "isNotCarrying", "isNotSwimming"]] call FUNC(canInteractWith)) || {_caller == _unit}) exitWith {_vehicle}; +if (!([_caller, _unit, ["isNotDragging", "isNotCarrying", "isNotSwimming"]] call FUNC(canInteractWith)) || {_caller == _unit}) exitWith { objNull }; // Try to use nearest vehicle if a vehicle hasn't been supplied if (isNull _vehicle) then { @@ -30,6 +31,7 @@ if (isNull _vehicle) then { if (!isNull _vehicle) then { [_unit, true, GROUP_SWITCH_ID, side group _caller] call FUNC(switchToGroupSide); + TRACE_3("sending ace_loadPersonEvent",_unit,_vehicle,_caller); ["ace_loadPersonEvent", [_unit, _vehicle, _caller], _unit] call CBA_fnc_targetEvent; }; diff --git a/addons/common/functions/fnc_loadPersonLocal.sqf b/addons/common/functions/fnc_loadPersonLocal.sqf index 109e7e8e77..0426a94582 100644 --- a/addons/common/functions/fnc_loadPersonLocal.sqf +++ b/addons/common/functions/fnc_loadPersonLocal.sqf @@ -17,15 +17,11 @@ * Public: Yes */ -params ["_unit", "_vehicle", "_caller"]; - -// if (!alive _unit) then { -// _unit = [_unit, _caller] call makeCopyOfBody; //func does not exist -// }; +params ["_unit", "_vehicle", ["_caller", objNull]]; +TRACE_3("loadPersonLocal",_unit,_vehicle,_caller); private _slotsOpen = false; - -if (_vehicle emptyPositions "cargo" > 0) then { +if ((_vehicle emptyPositions "cargo" > 0) && {!(_unit getVariable ['ACE_isUnconscious', false])} || {(getNumber (configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "ejectDeadCargo")) == 0}) then { _unit moveInCargo _vehicle; _slotsOpen = true; } else { @@ -35,29 +31,16 @@ if (_vehicle emptyPositions "cargo" > 0) then { }; }; -if (_slotsOpen) then { - private _loaded = _vehicle getVariable [QGVAR(loaded_persons),[]]; - _loaded pushBack _unit; +if (!_slotsOpen) exitWith { WARNING_2("no open seats %1->%2",_unit,_vehicle); }; - _vehicle setVariable [QGVAR(loaded_persons), _loaded, true]; - - if !([_unit] call FUNC(isAwake)) then { - [{ - (_this select 0) params ["_unit", "_vehicle"]; - - // wait until the unit is in the vehicle - if (vehicle _unit != _vehicle) exitWith { - // kill this pfh if either one is deleted - if (isNull _unit || isNull _vehicle) then { - [_this select 1] call CBA_fnc_removePerFrameHandler; - }; - }; - - _unit setVariable [QEGVAR(medical,vehicleAwakeAnim), [_vehicle, animationState _unit]]; - - [_unit, [_unit] call FUNC(getDeathAnim), 1, true] call FUNC(doAnimation); - - [_this select 1] call CBA_fnc_removePerFrameHandler; - }, 0.5, [_unit, _vehicle]] call CBA_fnc_addPerFrameHandler; - }; -}; +[{ // just for error reporting + params ["_unit", "_vehicle"]; + (alive _unit) && {alive _vehicle} && {(vehicle _unit) == _vehicle} +}, { + params ["_unit", "_vehicle"]; + TRACE_2("success",_unit,_vehicle); +}, [_unit, _vehicle], 2, { + params ["_unit", "_vehicle"]; + if (!alive _unit) exitWith {}; + WARNING_2("timeout %1->%2",_unit,_vehicle); +}] call CBA_fnc_waitUntilAndExecute; diff --git a/addons/common/functions/fnc_nearestVehiclesFreeSeat.sqf b/addons/common/functions/fnc_nearestVehiclesFreeSeat.sqf index 30b0594b30..aba75ff60f 100644 --- a/addons/common/functions/fnc_nearestVehiclesFreeSeat.sqf +++ b/addons/common/functions/fnc_nearestVehiclesFreeSeat.sqf @@ -19,4 +19,8 @@ params ["_unit", ["_distance", 10]]; private _nearVehicles = nearestObjects [_unit, ["Car", "Air", "Tank", "Ship_F", "Pod_Heli_Transport_04_crewed_base_F"], _distance]; -_nearVehicles select {(_x emptyPositions "cargo" > 0) || {_x emptyPositions "gunner" > 0}} +_nearVehicles select { + // Filter cargo seats that will eject unconscious units (e.g. quad bike) + ((_x emptyPositions "cargo" > 0) && {!(_unit getVariable ['ACE_isUnconscious', false])} || {(getNumber (configFile >> "CfgVehicles" >> (typeOf _x) >> "ejectDeadCargo")) == 0}) + || {_x emptyPositions "gunner" > 0} +} diff --git a/addons/common/functions/fnc_registerItemReplacement.sqf b/addons/common/functions/fnc_registerItemReplacement.sqf new file mode 100644 index 0000000000..d70a718193 --- /dev/null +++ b/addons/common/functions/fnc_registerItemReplacement.sqf @@ -0,0 +1,112 @@ +#include "script_component.hpp" +/* + * Author: BaerMitUmlaut + * Registers an event handler that replaces an item or item type with one or + * more other items. + * + * Arguments: + * 0: Item or item type ID to replace + * 1: Item or list of items + * 2: Replace items that inherit from original item (only if 0 is STRING) (Optional) + * + * Return Value: + * None + * + * Example: + * ["FirstAidKit", "ACE_fieldDressing"] call ace_common_fnc_registerItemReplacement + * + * Public: Yes + */ +params [["_oldItem", "", [0,""]], ["_newItems", "", ["", []]], ["_replaceInherited", false, [false]]]; +TRACE_3("registerItemReplacement",_oldItem,_newItems,_replaceInherited); + +// CBA player event handler function +private _fnc_replaceItems = { + params ["_unit"]; + + private _items = items _unit; + if (_items isEqualTo GVAR(oldItems)) exitWith {}; + + private _newItems = _items - GVAR(oldItems); + if (_newItems isEqualTo []) exitWith { + GVAR(oldItems) = _items; + }; + + _newItems sort true; // Sort so all items of current class can be replaced at once + private _cfgWeapons = configFile >> "CfgWeapons"; // Microoptimization + + for "_i" from 0 to count _newItems - 1 do { + private _item = _newItems#_i; + + // Determine replacement items: direct replacements, ... + private _replacements = GVAR(itemReplacements) getVariable [_item, []]; + + // ... item type replacements ... + private _type = getNumber (_cfgWeapons >> _item >> "ItemInfo" >> "type"); + private _typeReplacements = GVAR(itemReplacements) getVariable ["$" + str _type, []]; + _replacements append _typeReplacements; + + // ... and inherited replacements + { + if (_item isKindOf [_x, _cfgWeapons]) then { + private _inheritedReplacements = GVAR(itemReplacements) getVariable [_x, []]; + _replacements append _inheritedReplacements; + }; + } forEach GVAR(inheritedReplacements); + + // Skip lookup for all following items of this class + private _count = 1; + while {_newItems#(_i + 1) == _item} do { // (i+1) can be out of bounds, but should fail safely + _count = _count + 1; + _i = _i + 1; + }; + + // Replace all items of current class in list + if !(_replacements isEqualTo []) then { + TRACE_3("replace",_item,_count,_replacements); + _unit removeItems _item; + + for "_j" from 1 to _count do { + { [_unit, _x] call FUNC(addToInventory) } forEach _replacements; + }; + }; + }; + + GVAR(oldItems) = items _unit; +}; + +// Setup on first run +if (isNil QGVAR(itemReplacements)) then { + GVAR(itemReplacements) = [] call CBA_fnc_createNamespace; + GVAR(inheritedReplacements) = []; + GVAR(oldItems) = []; + ["loadout", _fnc_replaceItems] call CBA_fnc_addPlayerEventHandler; +}; + +// Save item replacement +// $ prefix is used for types (numbers) and replacements with inheritance +if (_replaceInherited) then { + _oldItem = "$" + _oldItem; + GVAR(inheritedReplacements) pushBack _oldItem; +}; +if (_oldItem isEqualType 0) then { + _oldItem = "$" + str _oldItem; +}; +if (_newItems isEqualType "") then { + _newItems = [_newItems]; +}; + +private _oldReplacements = GVAR(itemReplacements) getVariable [_oldItem, []]; +_oldReplacements append _newItems; +GVAR(itemReplacements) setVariable [_oldItem, _newItems]; + +// Force item scan when new replacement was registered in PostInit +if (!isNull ACE_player) then { + GVAR(oldItems) = []; + + // Exec next frame to ensure full scan only runs once per frame + // For example, if item replacements are registred in PostInit (due to CBA + // settings) by different addons, the inventory is only scanned once in the + // next frame, not once per addon. + [_fnc_replaceItems, [ACE_player]] call CBA_fnc_execNextFrame; +}; diff --git a/addons/common/functions/fnc_setDisableUserInputStatus.sqf b/addons/common/functions/fnc_setDisableUserInputStatus.sqf index 3fdc185325..843837caba 100644 --- a/addons/common/functions/fnc_setDisableUserInputStatus.sqf +++ b/addons/common/functions/fnc_setDisableUserInputStatus.sqf @@ -16,7 +16,8 @@ * Public: Yes */ -params ["_id", "_disable"]; +params [["_id", "#", [""]], ["_disable", false, [false]]]; +TRACE_2("setDisableUserInputStatus",_id,_disable); if (isNil QGVAR(DISABLE_USER_INPUT_COLLECTION)) then { GVAR(DISABLE_USER_INPUT_COLLECTION) = []; diff --git a/addons/common/functions/fnc_uniqueItems.sqf b/addons/common/functions/fnc_uniqueItems.sqf index 48f91831b9..5d7e5e8633 100644 --- a/addons/common/functions/fnc_uniqueItems.sqf +++ b/addons/common/functions/fnc_uniqueItems.sqf @@ -11,7 +11,7 @@ * Items * * Example: - * [_player] call ace_common_fnc_uniqueItems + * [player] call ace_common_fnc_uniqueItems * * Public: No */ @@ -28,12 +28,10 @@ private _fnc_getItems = { // Use cached items list if unit is ACE_player if (_unit isEqualTo ACE_player) then { - private _items = GVAR(uniqueItemsCache); - if (isNil "_items") then { - _items = call _fnc_getItems; - GVAR(uniqueItemsCache) = _items; + if (isNil QGVAR(uniqueItemsCache)) then { + GVAR(uniqueItemsCache) = call _fnc_getItems; }; - +_items + +GVAR(uniqueItemsCache) } else { call _fnc_getItems; }; diff --git a/addons/common/functions/fnc_unloadPerson.sqf b/addons/common/functions/fnc_unloadPerson.sqf index b744cbc272..5f435a1455 100644 --- a/addons/common/functions/fnc_unloadPerson.sqf +++ b/addons/common/functions/fnc_unloadPerson.sqf @@ -15,18 +15,16 @@ * Public: No */ -#define GROUP_SWITCH_ID QFUNC(loadPerson) - params ["_unit"]; +TRACE_1("unloadPerson",_unit); private _vehicle = vehicle _unit; +if (isNull _vehicle) exitWith {false}; if (_vehicle == _unit) exitWith {false}; if (speed _vehicle > 1 || {((getPos _vehicle) select 2) > 2}) exitWith {false}; -if (!isNull _vehicle) then { - ["ace_unloadPersonEvent", [_unit, _vehicle], [_unit]] call CBA_fnc_targetEvent; -}; +["ace_unloadPersonEvent", [_unit, _vehicle], [_unit]] call CBA_fnc_targetEvent; true diff --git a/addons/common/functions/fnc_unloadPersonLocal.sqf b/addons/common/functions/fnc_unloadPersonLocal.sqf index bf33ffab89..1333304d1f 100644 --- a/addons/common/functions/fnc_unloadPersonLocal.sqf +++ b/addons/common/functions/fnc_unloadPersonLocal.sqf @@ -20,11 +20,19 @@ #define GROUP_SWITCH_ID QFUNC(loadPerson) params ["_unit", "_vehicle", ["_unloader", objNull]]; -TRACE_3("params",_unit,_vehicle,_unloader); +TRACE_3("unloadpersonLocal",_unit,_vehicle,_unloader); //This covers testing vehicle stability and finding a safe position private _emptyPos = [_vehicle, (typeOf _unit), _unloader] call EFUNC(common,findUnloadPosition); TRACE_1("findUnloadPosition",_emptyPos); +if (_emptyPos isEqualTo []) then { + _emptyPos = [_vehicle, (typeOf _unit), _unloader] call EFUNC(common,findUnloadPosition); + TRACE_1("findUnloadPosition 2nd attempt",_emptyPos); + if (_emptyPos isEqualTo []) then { + _emptyPos = [_vehicle, (typeOf _unit), _unloader] call EFUNC(common,findUnloadPosition); + TRACE_1("findUnloadPosition 3rd attempt",_emptyPos); + }; +}; 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); @@ -38,57 +46,22 @@ if (count _emptyPos != 3) exitwith { unassignVehicle _unit; [_unit] orderGetIn false; -private _resetUncon = false; -if (lifeState _unit == "INCAPACITATED") then { - _resetUncon = true; - _unit setUnconscious false; - TRACE_1("pausing setUnconscious",_unit); -}; - TRACE_1("Ejecting", alive _unit); _unit action ["Eject", vehicle _unit]; [{ - params ["_unit", "_emptyPos", "_resetUncon"]; - - if ((vehicle _unit) != _unit) then { - WARNING_2("Failed to unload in time [%1 - %2]",_unit, vehicle _unit); - }; - + params ["_unit", "_emptyPos"]; + (alive _unit) && {(vehicle _unit) != _unit} +}, { + params ["_unit", "_emptyPos"]; + TRACE_2("success",_unit,_emptyPos); _unit setPosASL AGLToASL _emptyPos; - - if (_resetUncon) then { - TRACE_1("resuming setUnconscious",_unit); - // This should reset the unit to an Unconscious animation - // Also has the hilarious effect of violently ragdolling the guy - _unit setUnconscious true; - }; - - // ToDo [medical-rewrite]: verify we can remove the following commented code - - // if !([_unit] call FUNC(isAwake)) then { - // TRACE_1("Check if isAwake", [_unit] call FUNC(isAwake)); - - // if (driver _unit == _unit) then { - // private _anim = [_unit] call FUNC(getDeathAnim); - - // [_unit, _anim, 1, true] call FUNC(doAnimation); - - // [{ - // params ["_unit", "_anim"]; - // if ((_unit getVariable "ACE_isUnconscious") and (animationState _unit != _anim)) then { - // [_unit, _anim, 2, true] call FUNC(doAnimation); - // }; - // }, [_unit, _anim], 0.5] call CBA_fnc_waitAndExecute; - // }; - // }; -}, [_unit, _emptyPos, _resetUncon], 0.5] call CBA_fnc_waitAndExecute; +}, [_unit, _emptyPos], 2, { + params ["_unit", "_emptyPos"]; + if (!alive _unit) exitWith {}; + WARNING_2("timeout %1->%2",_unit,vehicle _unit); +}] call CBA_fnc_waitUntilAndExecute; [_unit, false, GROUP_SWITCH_ID, side group _unit] call FUNC(switchToGroupSide); -private _loaded = _vehicle getvariable [QGVAR(loaded_persons),[]]; -_loaded deleteAt (_loaded find _unit); - -_vehicle setvariable [QGVAR(loaded_persons), _loaded, true]; - true diff --git a/addons/common/functions/fnc_watchVariable.sqf b/addons/common/functions/fnc_watchVariable.sqf index 6fa86dc9bc..b3ec33bddc 100644 --- a/addons/common/functions/fnc_watchVariable.sqf +++ b/addons/common/functions/fnc_watchVariable.sqf @@ -20,7 +20,7 @@ * Example: * ["CBA_missionTime"] call ace_common_fnc_watchVariable // Uses title as code * ["diag_frameNo", {diag_frameNo}, [false]] call ace_common_fnc_watchVariable // Won't show delta - * ["blood", {player getVariable "ace_medical_bloodVolume"}, [true, 0, 100]] call ace_common_fnc_watchVariable // Shows slider + * ["blood", {player getVariable "ace_medical_bloodVolume"}, [true, 0, 6]] call ace_common_fnc_watchVariable // Shows slider * ["multiLine text", {"Line 1
Line 2"}, [2]] call ace_common_fnc_watchVariable * ["player names", {allPlayers apply {name _x}}, [5]] call ace_common_fnc_watchVariable // handles any data types * diff --git a/addons/common/init_versionTooltip.sqf b/addons/common/init_versionTooltip.sqf deleted file mode 100644 index ce0d005a14..0000000000 --- a/addons/common/init_versionTooltip.sqf +++ /dev/null @@ -1,59 +0,0 @@ -#include "script_component.hpp" - -#define MAX_COUNT 30 -#define ANIM_TIME 10 - -private _display = findDisplay 0; - -if (!scriptDone (_display getVariable [QGVAR(versionTooltip), scriptNull])) exitWith {}; - -_display setVariable [QGVAR(versionTooltip), [_display] spawn { - disableSerialization; - - params ["_display"]; - - private _allControls = []; - - private _fnc_create = { - private _ctrl = _display ctrlCreate ["RscPicture", -1]; - - // randomize size - private _size = selectRandom [safezoneW / 30, safezoneW / 20, safezoneW / 15]; - private _position = [ - random safezoneW + safezoneX - _size / 2, - - random (safezoneH / 5) + safezoneY - _size, - _size, - _size - ]; - - _ctrl ctrlSetPosition _position; - _ctrl ctrlCommit 0; - - // pls ignore - _ctrl ctrlSetText QPATHTOF(data\icon_banana_ca.paa); - - // animate with random speed - _position set [1, 1 - safezoneY]; - _ctrl ctrlSetPosition _position; - _ctrl ctrlCommit (ANIM_TIME * random [0.5, 1, 1.5]); - - _allControls pushBack _ctrl; - }; - - while {!isNull _display} do { - _allControls = _allControls select { - if (ctrlCommitted _x) then { - ctrlDelete _x; - false - } else { - true - }; - }; - - while {count _allControls < MAX_COUNT} do { - call _fnc_create; - }; - - uiSleep 3; - }; -}]; diff --git a/addons/common/script_component.hpp b/addons/common/script_component.hpp index 9eb8af601f..5eb318a9bf 100644 --- a/addons/common/script_component.hpp +++ b/addons/common/script_component.hpp @@ -16,10 +16,6 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define VERSION_CONFIG_COMMON VERSION_CONFIG;\ - versionDesc = "ACE 3";\ - versionAct = QUOTE(call COMPILE_FILE(init_versionTooltip)) - #define DIG_SURFACE_BLACKLIST [ \ "concrete", "concrete_exp", "concrete_int", "int_concrete", "int_concrete_exp", \ diff --git a/addons/common/scripts/checkVersionNumber.sqf b/addons/common/scripts/checkVersionNumber.sqf index 5d4b1734e4..15832ed2bd 100644 --- a/addons/common/scripts/checkVersionNumber.sqf +++ b/addons/common/scripts/checkVersionNumber.sqf @@ -99,6 +99,7 @@ if (!isServer) then { diag_log text _error; [QGVAR(systemChatGlobal), _error] call CBA_fnc_globalEvent; + [QGVAR(serverLog), _error] call CBA_fnc_serverEvent; }; private _missingAddonServer = false; @@ -116,6 +117,7 @@ if (!isServer) then { diag_log text _error; [QGVAR(systemChatGlobal), _error] call CBA_fnc_globalEvent; + [QGVAR(serverLog), _error] call CBA_fnc_serverEvent; }; private _oldVersionClient = false; @@ -133,6 +135,7 @@ if (!isServer) then { diag_log text _error; [QGVAR(systemChatGlobal), _error] call CBA_fnc_globalEvent; + [QGVAR(serverLog), _error] call CBA_fnc_serverEvent; }; private _oldVersionServer = false; @@ -150,6 +153,7 @@ if (!isServer) then { 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 5e354ab8e2..474665f32a 100644 --- a/addons/common/stringtable.xml +++ b/addons/common/stringtable.xml @@ -10,6 +10,8 @@ 通用 일반 Ogólny + Общий + Comum ACE-Team @@ -27,7 +29,7 @@ ACE-製作團隊 ACE-制作团队 - + Advanced Усложненный Zaawansowany @@ -410,7 +412,7 @@ 未知的 未知的 - + Normal Normal Normale @@ -506,30 +508,39 @@ Check PBO Action + PBO Überprüfung Controlla Azioni PBO 檢查PBO動作 检查PBO动作 PBO 検査の挙動 PBO 검사 Sprawdź akcję PBO + Действие при проверке PBO + Ação de Checar PBO Check PBO All + Alle PBOs überprüfen Controlla Tutti i PBO 檢查所有PBO 检查所有PBO PBO 全てを検査 모든 PBO 검사 Sprawdź wszystkie PBO + Проверять все PBO + Checar Todos os PBOs Check PBO Whitelist + PBO Whitelist Controlla Whitelist PBO 檢查PBO白名單 检查PBO白名单 許可リスト内の PBO を検査 검사 제외 PBO Sprawdź białą listę PBO + Белый список для проверки PBO + Lista Branca de PBO Feedback icons @@ -669,6 +680,7 @@ 保持武器雷射/手電筒的狀態 保持武器雷射/手电筒的状态 Trwały znacznik laserowy/latarka + Luz da lanterna/laser da arma persistente Enable gunlight after weapon switch or vehicle enter/exit if it was previously enabled. @@ -680,6 +692,7 @@ 保存武器雷射/手電筒的開關狀態,使玩家切換武器或進出載具時能保持之前的的狀態 保存武器雷射/手电筒的开关状态,使玩家切换武器或进出载具时能保持之前的的状态。 Aktywuj znacznik laserowy/latarkę po zmianie broni lub wejściu/wyjściu z pojazdu, jeśli był on poprzednio włączony. + Ativa a luz da arma ao trocar de arma, entrar/sair de um veículo. Caso tenha sido acesa anteriormente. Banana @@ -998,10 +1011,14 @@ 啟用 启用 - + Always + Immer + 常に + Всегда + Sempre - + Anywhere Где угодно Wszędzie @@ -1009,13 +1026,13 @@ Überall Kdekoliv Qualquer lugar - PArtout + Partout Akárhol Ovunque どこでも 어디서나 - + Basic Базовый Podstawowy @@ -1030,7 +1047,7 @@ 기본 - Medical vehicles + Medical Vehicles В медицинском транспорте Pojazdy medyczne Vehiculos médicos @@ -1077,9 +1094,17 @@ Confirm + 確認 + Bestätigen + Подтвердить + Confirmar Never + 行わない + Nie + Никогда + Nunca Vehicles only @@ -1257,6 +1282,8 @@ 音楽の音量低下を許可 Permesso di abbassare la musica Zezwól na przyciszanie muzyki + Разрешить приглушение музыки + Permite diminuir volume da música Allow ACE scripts to turn down the music. @@ -1267,22 +1294,62 @@ ACE スプリントへ音量低下を許可します。 Permetti agli script di ACEdi abbassare la musica. Zezwól skrypty ACE na przyciszanie muzyki. + Позволить скриптам ACE приглушать музыку + Permite que Scripts do ACE diminuam o volume da música. Flag (ACE - Black) + Flagge (Ace - Schwarz) 旗帜(ACE-黑色): 旗幟(ACE-黑色) Bandiera (ACE - Nera) 旗 (ACE - 黒) Flaga (ACE - Czarna) + Флаг (ACE - Черный) + Bandeira (ACE - Preto) Flag (ACE - White) + Flagge (Ace - Weiß) 旗帜(ACE-白色): 旗幟(ACE-白色) Bandiera (ACE - Bianca) 旗 (ACE - 白) Flaga (ACE - Biała) + Флаг (ACE - Белый) + Bandeira (ACE - Branco) + + + Players only + Игроков + Tylko dla graczy + Solo jugadores + Nur Spieler + Pouze hráči + Somente jogadores + Joueur uniquement + Csak játékosok + Solo giocatori + プレイヤーのみ + 플레이어만 + 只限玩家 + 只限玩家 + + + Players and AI + Игроков и ботов + Gracze oraz AI + Jugadores e IA + Spieler und KI + Hráči a AI + Jogadores e IA + Joueurs et IA + Játékosok és AI + Giocatori ed IA + プレイヤーと AI + 플레이어 및 인공지능 + 玩家与AI + 玩家與AI diff --git a/addons/cookoff/functions/fnc_detonateAmmunition.sqf b/addons/cookoff/functions/fnc_detonateAmmunition.sqf index f77a2755fd..0d944958d2 100644 --- a/addons/cookoff/functions/fnc_detonateAmmunition.sqf +++ b/addons/cookoff/functions/fnc_detonateAmmunition.sqf @@ -87,7 +87,7 @@ if (_amountOfMagazines > 0) exitWith { playSound3D [_sound, objNull, false, (getPosASL _vehicle), 2, 1, 1300]; if (random 1 < 0.15) then { - [_vehicle, _ammo, _speed, random 1 < 0.15] call _spawnProjectile; + [_vehicle, _ammo, _speed, true] call _spawnProjectile; }; }; if (toLower _simType == "shotgrenade") then { diff --git a/addons/cookoff/stringtable.xml b/addons/cookoff/stringtable.xml index 536700cc87..19ef4ed3d2 100644 --- a/addons/cookoff/stringtable.xml +++ b/addons/cookoff/stringtable.xml @@ -11,12 +11,22 @@ ACE Durchzündung ACE Cook off ACE Samozapłon + ACE Возгорание + ACE Cook off Damage handling and turret effects + Schadensberechnung und Geschützturmeffekte + 損傷処理と砲塔の効果 + Обработка урона и эффектов срыва башни + Manipulação de dano e efeitos de torre Changes damage handling for cook off and turret explosion effects + Ä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 Wreck (Turret) @@ -43,6 +53,8 @@ Abilita esplosione cassa munizioni 開啟彈藥箱殉爆效果 开启弹药箱殉爆效果 + Разрешить возгорание ящиков с боеприпасами + Permitir cozinhar caixas de munição Enables cooking off of ammo boxes. @@ -54,6 +66,8 @@ Abilita l'esplosione della cassa di munizioni. 開啟彈藥箱殉爆效果 开启弹药箱殉爆效果 + Активирует возгорание ящиков с боеприпасами + Permitir que caixas de munição cozinhem. Enable Ammunition cook off @@ -65,6 +79,8 @@ Abilita Esplosione munizioni 開啟彈藥殉爆效果 开启弹药殉爆效果 + Разрешить детонацию боекомплекта + Permitir cozinhar munição Enables Ammunition cook off. Fires ammunition projectiles while vehicle is on fire and has ammunition. @@ -76,6 +92,8 @@ 開啟彈藥殉爆效果。當一台載有彈藥的載具起火時, 將會有殉爆的效果 开启弹药殉爆效果。当一台载有弹药的载具起火时, 将会有殉爆的效果。 쿡오프 현상을 활성화 합니다. 이것은 탄약에 불이 붙어있는 동안 주변에 발사체를 발사합니다. + Активирует возгорание и детонацию боекомплекта в горящей технике + Permite que a munição cozinhe. Dispara projéteis de munição enquanto o veículo está em chamas e tem munição. Ammunition cook off duration @@ -87,6 +105,8 @@ 彈藥殉爆效果持續時間 弹药殉爆效果持续时间 쿡오프 지속 시간 + Длительность возгорания боеприпасов + Duração do cozinhamento de munição Multiplier for how long cook off lasts [Setting to 0 will disable ammo cookoff] @@ -98,6 +118,8 @@ 設定彈藥殉爆效果會持續多久時間 [輸入0來關閉殉爆效果] 设定弹药殉爆效果会持续多久时间 [输入0来关闭殉爆效果] 쿡오프 지속 시간의 배수 [0 이면 비활성] + Множитель длительности возгорания [0 - отключает возгорание боеприпасов] + Multiplicação da duração do cozinhamento [0 faz com que o cozinhamento seja desativado] Cook-off probability coefficient @@ -108,6 +130,8 @@ 殉爆发生机率系数 Coefficient de probabilité du cook off Współczynnik prawdopodobieństwa samozapłonu + Коэффициент вероятности возгорания + Probabilidade de Cozinhar Multiplier for cook-off probability. Higher value results in higher cook-off probability @@ -118,6 +142,8 @@ 调整殉爆发生机率系数。值越高代表越容易发生殉爆。 Multiplicateur pour la probabilité du cook off. Plus la valeur est élevée, plus la probabilité de cook off est haute. 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. diff --git a/addons/csw/$PBOPREFIX$ b/addons/csw/$PBOPREFIX$ new file mode 100644 index 0000000000..366f3a5648 --- /dev/null +++ b/addons/csw/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\csw \ No newline at end of file diff --git a/addons/csw/Cfg3den.hpp b/addons/csw/Cfg3den.hpp new file mode 100644 index 0000000000..dfac0f5475 --- /dev/null +++ b/addons/csw/Cfg3den.hpp @@ -0,0 +1,38 @@ +class ctrlCombo; +class Cfg3DEN { + class Attributes { + class Title; + class Combo: Title { + class Controls { + class 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/CfgEventHandlers.hpp b/addons/csw/CfgEventHandlers.hpp new file mode 100644 index 0000000000..afe6392a7c --- /dev/null +++ b/addons/csw/CfgEventHandlers.hpp @@ -0,0 +1,15 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_FILE(XEH_preStart)); + }; +}; +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_FILE(XEH_preInit)); + }; +}; +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE( call COMPILE_FILE(XEH_postInit) ); + }; +}; diff --git a/addons/csw/CfgMagazineGroups.hpp b/addons/csw/CfgMagazineGroups.hpp new file mode 100644 index 0000000000..697403f963 --- /dev/null +++ b/addons/csw/CfgMagazineGroups.hpp @@ -0,0 +1,86 @@ +class GVAR(groups) { + // A3 .50 BMG (12.7x99mm) + class GVAR(100Rnd_127x99_mag) { + 500Rnd_127x99_mag = 1; + 200Rnd_127x99_mag = 1; + 100Rnd_127x99_mag = 1; + rhs_mag_100rnd_127x99_mag = 1; + rhs_mag_200rnd_127x99_mag = 1; + CUP_100Rnd_127x99_M = 1; + }; + class GVAR(100Rnd_127x99_mag_red) { + 500Rnd_127x99_mag_Tracer_Red = 1; + 200Rnd_127x99_mag_Tracer_Red = 1; + 100Rnd_127x99_mag_Tracer_Red = 1; + rhs_mag_100rnd_127x99_mag_Tracer_Red = 1; + rhs_mag_200rnd_127x99_mag_Tracer_Red = 1; + CUP_100Rnd_TE4_Red_Tracer_127x99_M = 1; + }; + class GVAR(100Rnd_127x99_mag_green) { + 500Rnd_127x99_mag_Tracer_Green = 1; + 200Rnd_127x99_mag_Tracer_Green = 1; + 100Rnd_127x99_mag_Tracer_Green = 1; + rhs_mag_100rnd_127x99_mag_Tracer_Green = 1; + CUP_100Rnd_TE4_Green_Tracer_127x99_M = 1; + }; + class GVAR(100Rnd_127x99_mag_yellow) { + 500Rnd_127x99_mag_Tracer_Yellow = 1; + 200Rnd_127x99_mag_Tracer_Yellow = 1; + 100Rnd_127x99_mag_Tracer_Yellow = 1; + rhs_mag_100rnd_127x99_mag_Tracer_Yellow = 1; + CUP_100Rnd_TE4_Yellow_Tracer_127x99_M = 1; + }; + + // Soviet HMG (12.7x108mm) + class GVAR(50Rnd_127x108_mag) { + rhs_mag_127x108mm_50 = 1; + rhs_mag_127x108mm_100 = 1; + rhs_mag_127x108mm_150 = 1; + rhs_mag_127x108mm_300 = 1; + CUP_150Rnd_127x108_KORD_M = 1; + CUP_50Rnd_127x108_KORD_M = 1; + CUP_50Rnd_TE3_LRT5_127x107_DSHKM_M = 1; // not sure why cup uses 107 for the DSHKM? + CUP_150Rnd_TE3_LRT5_127x107_DSHKM_M = 1; + }; + + // A3 20mm GMG + class GVAR(20Rnd_20mm_G_belt) { + 40Rnd_20mm_G_belt = 1; + 200Rnd_20mm_G_belt = 1; + }; + + // A3 82mm mortar shells (Allows the normal mk6 to be reloaded from the mk6 ammo handling mags) + class ACE_1Rnd_82mm_Mo_HE { + ACE_1Rnd_82mm_Mo_HE = 1; + 8Rnd_82mm_Mo_shells = 1; + rhs_12Rnd_m821_HE = 1; + rhs_mag_3vo18_10 = 1; + }; + class ACE_1Rnd_82mm_Mo_Smoke { + ACE_1Rnd_82mm_Mo_Smoke = 1; + 8Rnd_82mm_Mo_Smoke_white = 1; + rhs_mag_d832du_10 = 1; + }; + class ACE_1Rnd_82mm_Mo_Illum { + ACE_1Rnd_82mm_Mo_Illum = 1; + 8Rnd_82mm_Mo_Flare_white = 1; + rhs_mag_3vs25m_10 = 1; + }; + class ACE_1Rnd_82mm_Mo_HE_Guided { + ACE_1Rnd_82mm_Mo_HE_Guided = 1; + 8Rnd_82mm_Mo_guided = 1; + }; + class ACE_1Rnd_82mm_Mo_HE_LaserGuided { + ACE_1Rnd_82mm_Mo_HE_LaserGuided = 1; + 8Rnd_82mm_Mo_LG = 1; + }; + + // A3 Titans (Spike) - just use handheld magazines + class Titan_AT { + 1Rnd_GAT_missiles = 1; + }; + class Titan_AA { + 1Rnd_GAA_missiles = 1; + }; +}; + diff --git a/addons/csw/CfgMagazines.hpp b/addons/csw/CfgMagazines.hpp new file mode 100644 index 0000000000..6102fa48f4 --- /dev/null +++ b/addons/csw/CfgMagazines.hpp @@ -0,0 +1,65 @@ +class CfgMagazines { + class 100Rnd_127x99_mag; + class GVAR(100Rnd_127x99_mag): 100Rnd_127x99_mag { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(127x99_displayName); + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; + picture = QPATHTOF(UI\ammoBox_50bmg_ca.paa); + type = 256; + mass = 96; + ACE_isBelt = 1; + }; + class 100Rnd_127x99_mag_Tracer_Red; + class GVAR(100Rnd_127x99_mag_red): 100Rnd_127x99_mag_Tracer_Red { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(127x99_red_displayName); + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; + picture = QPATHTOF(UI\ammoBox_50bmg_ca.paa); + type = 256; + mass = 96; + ACE_isBelt = 1; + }; + class 100Rnd_127x99_mag_Tracer_Green; + class GVAR(100Rnd_127x99_mag_green): 100Rnd_127x99_mag_Tracer_Green { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(127x99_green_displayName); + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; + picture = QPATHTOF(UI\ammoBox_50bmg_ca.paa); + type = 256; + mass = 96; + ACE_isBelt = 1; + }; + class 100Rnd_127x99_mag_Tracer_Yellow; + class GVAR(100Rnd_127x99_mag_yellow): 100Rnd_127x99_mag_Tracer_Yellow { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(127x99_yellow_displayName); + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; + picture = QPATHTOF(UI\ammoBox_50bmg_ca.paa); + type = 256; + mass = 96; + ACE_isBelt = 1; + }; + + class 50Rnd_127x108_Ball; + class GVAR(50Rnd_127x108_mag): 50Rnd_127x108_Ball { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(127x108_displayName); + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; + picture = QPATHTOF(UI\ammoBox_50bmg_ca.paa); + type = 256; + mass = 50; + ACE_isBelt = 1; + }; + + class 40Rnd_20mm_G_belt; + class GVAR(20Rnd_20mm_G_belt): 40Rnd_20mm_G_belt { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(GMGBelt_displayName); + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; + picture = QPATHTOF(UI\ammoBox_50bmg_ca.paa); + type = 256; + count = 20; + mass = 96; + ACE_isBelt = 1; + }; +}; diff --git a/addons/csw/CfgVehicles.hpp b/addons/csw/CfgVehicles.hpp new file mode 100644 index 0000000000..c1b8f11d3f --- /dev/null +++ b/addons/csw/CfgVehicles.hpp @@ -0,0 +1,245 @@ +class CfgVehicles { + class Man; + class CAManBase: Man { + class ACE_SelfActions { + class GVAR(deploy) { + displayName = CSTRING(PlaceTripod_displayName); + condition = QUOTE(call FUNC(assemble_canDeployTripod)); + statement = QUOTE(call FUNC(assemble_deployTripod)); + exceptions[] = {}; + }; + }; + }; + + + // Tripods: + class ThingX; + class GVAR(baseTripod): ThingX { + side = 3; + typicalCargo[] = {}; + armor = 500000; + mapSize = 0.4; + nameSound = "Bunker"; + accuracy = 1000; + destrType = "DestructDefault"; + + EGVAR(dragging,canDrag) = 1; + EGVAR(dragging,dragPosition)[] = {0, 2, 0}; + EGVAR(dragging,canCarry) = 1; + EGVAR(dragging,carryPosition)[] = {0, 2, 0}; + + class ACE_Actions { + class ACE_MainActions { + displayName = CSTRING(genericTripod_displayName); + selection = ""; + distance = 2.5; + condition = "true"; + class GVAR(pickUp) { + displayName = CSTRING(Pickup_displayName); + condition = QUOTE(call FUNC(assemble_canPickupTripod)); + statement = QUOTE(call FUNC(assemble_pickupTripod)); + }; + class GVAR(mountWeapon) { + displayName = CSTRING(MountWeapon_displayName); + condition = QUOTE(call FUNC(assemble_canDeployWeapon)); + statement = QUOTE(call FUNC(assemble_deployWeapon)); + modifierFunction = QUOTE(call FUNC(assemble_deployWeaponModifier)); + }; + }; + }; + }; + class GVAR(m3Tripod): GVAR(baseTripod) { + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_m3_tripod.p3d); + displayName = CSTRING(m3Tripod_displayName); + class ADDON { + disassembleTo = QGVAR(m3CarryTripod); + }; + }; + class GVAR(m3TripodLow): GVAR(m3Tripod) { + class ADDON { + disassembleTo = QGVAR(m3CarryTripodLow); + }; + }; + class GVAR(kordTripod): GVAR(baseTripod) { + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ace_csw_tripod_kord.p3d); + displayName = CSTRING(kordTripod_displayName); + class ADDON { + disassembleTo = QGVAR(kordCarryTripod); + }; + }; + class GVAR(kordTripodLow): GVAR(kordTripod) { + class ADDON { + disassembleTo = QGVAR(kordCarryTripodLow); + }; + }; + class GVAR(sag30Tripod): GVAR(baseTripod) { + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ace_csw_tripod_ags30.p3d); + displayName = CSTRING(sag30Tripod_displayName); + class ADDON { + disassembleTo = QGVAR(sag30CarryTripod); + }; + }; + class GVAR(m220Tripod): GVAR(baseTripod) { + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ace_csw_tripod_m220.p3d); + displayName = CSTRING(m220Tripod_displayName); + class ADDON { + disassembleTo = QGVAR(m220CarryTripod); + }; + }; + class GVAR(spg9Tripod): GVAR(baseTripod) { + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ace_csw_tripod_spg9.p3d); + displayName = CSTRING(spg9_Tripod); + class ADDON { + disassembleTo = QGVAR(spg9CarryTripod); + }; + }; + class GVAR(mortarBaseplate): GVAR(baseTripod) { + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_mortarBaseplate.p3d); + displayName = CSTRING(mortarBaseplate_displayName); + class ADDON { + disassembleTo = QGVAR(carryMortarBaseplate); + }; + }; + + + // Static Weapons: + class LandVehicle; + class StaticWeapon: LandVehicle { + class ACE_Actions { + class ACE_MainActions { + class GVAR(getIn) { + displayName = CSTRING(GetIn_displayName); + condition = QUOTE(call FUNC(canGetIn)); + statement = QUOTE(call FUNC(getIn)); + }; + }; + }; + }; + + class StaticMGWeapon: StaticWeapon {}; + + class HMG_01_base_F: StaticMGWeapon { + // ENABLE_CSW_ATTRIBUTE; + class ADDON { + enabled = 1; + proxyWeapon = QGVAR(HMG_Static); + magazineLocation = "_target selectionPosition 'magazine'"; + disassembleWeapon = QGVAR(staticHMGCarry); // carry weapon [CfgWeapons] + disassembleTurret = QGVAR(m3TripodLow); // turret [CfgVehicles] + desiredAmmo = 100; + ammoLoadTime = 7; + ammoUnloadTime = 5; + }; + }; + + class HMG_01_high_base_F: HMG_01_base_F { + class ADDON { + enabled = 1; + proxyWeapon = QGVAR(HMG_Static); + magazineLocation = "_target selectionPosition 'magazine'"; + disassembleWeapon = QGVAR(staticHMGCarry); // carry weapon [CfgWeapons] + disassembleTurret = QGVAR(m3Tripod); // turret [CfgVehicles] + desiredAmmo = 100; + ammoLoadTime = 7; + ammoUnloadTime = 5; + }; + }; + + class HMG_01_A_base_F: HMG_01_base_F { + class ADDON { + enabled = 0; + }; + }; + + + 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] + magazineLocation = "_target selectionPosition 'magazine'"; + disassembleWeapon = QGVAR(staticGMGCarry); // carry weapon [CfgWeapons] + disassembleTurret = QGVAR(m3TripodLow); // turret [CfgVehicles] + desiredAmmo = 40; + ammoLoadTime = 7; + ammoUnloadTime = 5; + }; + }; + + class GMG_01_high_base_F: GMG_01_base_F { + class ADDON { + enabled = 1; + proxyWeapon = QGVAR(GMG_20mm); // Weapon Proxy (Shorter Reload Time) [CfgWeapons] + magazineLocation = "_target selectionPosition 'magazine'"; + disassembleWeapon = QGVAR(staticGMGCarry); // carry weapon [CfgWeapons] + disassembleTurret = QGVAR(m3Tripod); // turret [CfgVehicles] + desiredAmmo = 40; + ammoLoadTime = 7; + ammoUnloadTime = 5; + }; + }; + + class GMG_01_A_base_F: GMG_01_base_F { + class ADDON { + enabled = 0; + }; + }; + + + class AT_01_base_F: StaticMGWeapon { + // ENABLE_CSW_ATTRIBUTE; + class ADDON { + enabled = 1; + proxyWeapon = QGVAR(Titan_AT_Static); + magazineLocation = "_target selectionPosition 'magazine'"; + disassembleWeapon = QGVAR(staticATCarry); // carry weapon [CfgWeapons] + disassembleTurret = QGVAR(m3Tripod); // turret [CfgVehicles] + desiredAmmo = 40; + ammoLoadTime = 15; // 4 rounds per minute + ammoUnloadTime = 10; + }; + }; + + class AA_01_base_F: StaticMGWeapon { + // ENABLE_CSW_ATTRIBUTE; + class ADDON { + enabled = 1; + proxyWeapon = QGVAR(Titan_AA_Static); // Weapon Proxy (Shorter Reload Time) [CfgWeapons] + magazineLocation = "_target selectionPosition 'magazine'"; + disassembleWeapon = QGVAR(staticAACarry); // carry weapon [CfgWeapons] + disassembleTurret = QGVAR(m3Tripod); // turret [CfgVehicles] + desiredAmmo = 40; + ammoLoadTime = 15; // 4 rounds per minute + ammoUnloadTime = 10; + }; + }; + + + class StaticMortar: StaticWeapon {}; + class Mortar_01_base_F: StaticMortar { + // ENABLE_CSW_ATTRIBUTE; + class ADDON { + enabled = 1; + magazineLocation = ""; + disassembleWeapon = QGVAR(staticMortarCarry); // carry weapon [CfgWeapons] + disassembleTurret = QGVAR(mortarBaseplate); // turret [CfgVehicles] + desiredAmmo = 1; + ammoLoadTime = 3; + ammoUnloadTime = 3; + }; + }; +}; + diff --git a/addons/csw/CfgWeapons.hpp b/addons/csw/CfgWeapons.hpp new file mode 100644 index 0000000000..fd7a67d6f0 --- /dev/null +++ b/addons/csw/CfgWeapons.hpp @@ -0,0 +1,294 @@ +class CfgWeapons { + class Launcher; + class Launcher_Base_F: Launcher { + class WeaponSlotsInfo; + }; + + + // Tripods: + class GVAR(m3CarryTripod): Launcher_Base_F { + class ADDON { + type = "mount"; + deployTime = 4; + pickupTime = 4; + deploy = QGVAR(m3Tripod); + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 440; + }; + displayName = CSTRING(m3TripodFolded_displayName); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = QPATHTOF(UI\Tripod_Icon.paa); + }; + class GVAR(m3CarryTripodLow): GVAR(m3CarryTripod) { + class ADDON: ADDON { + deploy = QGVAR(m3TripodLow); + }; + displayName = CSTRING(m3TripodLowFolded_displayName); + }; + + class GVAR(kordCarryTripod): Launcher_Base_F { + class ADDON { + type = "mount"; + deployTime = 4; + pickupTime = 4; + deploy = QGVAR(kordTripod); + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 350; + }; + displayName = CSTRING(kordTripodFolded_displayName); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = QPATHTOF(UI\Tripod_Icon.paa); + }; + + class GVAR(kordCarryTripodLow): GVAR(kordCarryTripod) { + class ADDON: ADDON { + deploy = QGVAR(kordTripodLow); + }; + displayName = CSTRING(kordTripodFoldedLow_displayName); + }; + + class GVAR(m220CarryTripod): Launcher_Base_F { + class ADDON { + type = "mount"; + deployTime = 10; + pickupTime = 6; + deploy = QGVAR(m220Tripod); + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 210; + }; + displayName = CSTRING(m220TripodFolded_displayName); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = QPATHTOF(UI\Tripod_Icon.paa); + }; + + class GVAR(spg9CarryTripod): Launcher_Base_F { + class ADDON { + type = "mount"; + deployTime = 5; + pickupTime = 3; + deploy = QGVAR(spg9Tripod); + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 260; + }; + displayName = CSTRING(spg9_TripodFolded); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = QPATHTOF(UI\Tripod_Icon.paa); + }; + + class GVAR(sag30CarryTripod): Launcher_Base_F { + class ADDON { + type = "mount"; + deployTime = 4; + pickupTime = 4; + deploy = QGVAR(sag30Tripod); + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 260; + }; + displayName = CSTRING(sag30TripodFolded_displayName); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = QPATHTOF(UI\Tripod_Icon.paa); + }; + + class GVAR(carryMortarBaseplate): Launcher_Base_F { + class ADDON { + type = "mount"; + deployTime = 2; + pickupTime = 2; + deploy = QGVAR(mortarBaseplate); + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 290; // M3A1 baseblate weight + }; + displayName = CSTRING(mortarBaseplateBag_displayName); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = QPATHTOF(UI\Tripod_Icon.paa); // todo + }; + + + + // Weapons: + class GVAR(staticATCarry): Launcher_Base_F { + class ADDON { + type = "weapon"; + deployTime = 15; + pickupTime = 20; + class assembleTo { + GVAR(m3Tripod) = "B_static_AT_F"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 320; // 9M113 Konkurs Weight + }; + displayName = CSTRING(StaticATBag_displayName); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = QPATHTOF(UI\StaticAT_Icon.paa); + }; + + class GVAR(staticAACarry): GVAR(staticATCarry) { + class ADDON { + type = "weapon"; + deployTime = 15; + pickupTime = 20; + class assembleTo { + GVAR(m3Tripod) = "B_static_AA_F"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 320; + }; + displayName = CSTRING(StaticAABag_displayName); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = QPATHTOF(UI\StaticAT_Icon.paa); + }; + + class GVAR(staticHMGCarry): Launcher_Base_F { + class ADDON { + type = "weapon"; + deployTime = 7; + pickupTime = 10; + class assembleTo { + GVAR(m3Tripod) = "B_HMG_01_high_F"; + GVAR(m3TripodLow) = "B_HMG_01_F"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 840; + }; + displayName = CSTRING(StaticHMGBag_displayName); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = QPATHTOF(UI\StaticHGMG_Icon.paa); + }; + + class GVAR(staticGMGCarry): Launcher_Base_F { + class ADDON { + type = "weapon"; + deployTime = 5; + pickupTime = 6; + class assembleTo { + GVAR(m3Tripod) = "B_GMG_01_high_F"; + GVAR(m3TripodLow) = "B_GMG_01_F"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 780; + }; + displayName = CSTRING(StaticGMGBag_displayName); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = QPATHTOF(UI\StaticHGMG_Icon.paa); + }; + + + class GVAR(staticMortarCarry): Launcher_Base_F { + class ADDON { + type = "weapon"; + deployTime = 20; + pickupTime = 25; + class assembleTo { + GVAR(mortarBaseplate) = "B_Mortar_01_F"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 620; // M252 Mortar Weight + }; + displayName = CSTRING(mk6MortarBag_displayName); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = QPATHTOF(UI\StaticHGMG_Icon.paa); + }; + + // Proxy Weapons + CREATE_CSW_PROXY(HMG_Static); + CREATE_CSW_PROXY(GMG_20mm); + + class missiles_titan_static; + class EGVAR(javelin,Titan_Static): missiles_titan_static {}; // if ace_javelin does not exist, this will just inherit from the base weapon + class GVAR(Titan_AT_Static): EGVAR(javelin,Titan_Static) { + EGVAR(javelin,enabled) = 1; // needs to be explicitly enabled + magazineReloadTime = 0.5; + }; + class GVAR(Titan_AA_Static) : missiles_titan_static { + magazineReloadTime = 0.5; + }; + + + /* + class GVAR(staticAutoHMGCarry): Launcher_Base_F { + class ADDON { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + GVAR(m3Tripod) = GVAR(staticAutoHMGWeapon); + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 840; + }; + + displayName = CSTRING(StaticAutoHMGBag_displayName); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = QPATHTOF(UI\StaticHGMG_Icon.paa); + }; + + + class GVAR(staticAutoGMGCarry): Launcher_Base_F { + class GVAR(options) { + assembleTo = QGVAR(staticAutoGMGWeapon); + baseTripod = QGVAR(m3Tripod); + type = "weapon"; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 780; + }; + + displayName = CSTRING(StaticAutoGMGBag_displayName); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = QPATHTOF(UI\StaticHGMG_Icon.paa); + }; + + */ +}; + diff --git a/addons/csw/README.md b/addons/csw/README.md new file mode 100644 index 0000000000..8729a7fa31 --- /dev/null +++ b/addons/csw/README.md @@ -0,0 +1,12 @@ +ace_csw +=============== + +Crew Served Weapons - Static weapons that are served by multiple people + + +## Maintainers + +The people responsible for merging changes to this component or answering potential questions. + +- [TCVM](https://github.com/TheCandianVendingMachine) + diff --git a/addons/csw/UI/StaticAT_Icon.paa b/addons/csw/UI/StaticAT_Icon.paa new file mode 100644 index 0000000000..6dcf90093a Binary files /dev/null and b/addons/csw/UI/StaticAT_Icon.paa differ diff --git a/addons/csw/UI/StaticHGMG_Icon.paa b/addons/csw/UI/StaticHGMG_Icon.paa new file mode 100644 index 0000000000..12143ee2e1 Binary files /dev/null and b/addons/csw/UI/StaticHGMG_Icon.paa differ diff --git a/addons/csw/UI/Tripod_Icon.paa b/addons/csw/UI/Tripod_Icon.paa new file mode 100644 index 0000000000..02429a0e6d Binary files /dev/null and b/addons/csw/UI/Tripod_Icon.paa differ diff --git a/addons/csw/UI/ammoBox_50bmg_ca.paa b/addons/csw/UI/ammoBox_50bmg_ca.paa new file mode 100644 index 0000000000..6ceaa76fe0 Binary files /dev/null and b/addons/csw/UI/ammoBox_50bmg_ca.paa differ diff --git a/addons/csw/XEH_PREP.hpp b/addons/csw/XEH_PREP.hpp new file mode 100644 index 0000000000..7bde8c3c0f --- /dev/null +++ b/addons/csw/XEH_PREP.hpp @@ -0,0 +1,34 @@ +TRACE_1("",QUOTE(ADDON)); + +PREP(aceRearmGetCarryMagazines); + +PREP(ai_handleFired); + +PREP(assemble_canDeployTripod); +PREP(assemble_canDeployWeapon); +PREP(assemble_canPickupTripod); +PREP(assemble_canPickupWeapon); +PREP(assemble_deployTripod); +PREP(assemble_deployWeapon); +PREP(assemble_deployWeaponModifier); +PREP(assemble_pickupTripod); +PREP(assemble_pickupWeapon); + +PREP(canGetIn); +PREP(getIn); + +PREP(proxyWeapon); + +PREP(reload_actionsLoad); +PREP(reload_actionsUnload); +PREP(reload_canLoadMagazine); +PREP(reload_canUnloadMagazine); +PREP(reload_getLoadableMagazines); +PREP(reload_getVehicleMagazine); +PREP(reload_handleAddTurretMag); +PREP(reload_handleRemoveTurretMag); +PREP(reload_handleReturnAmmo); +PREP(reload_loadMagazine); + +PREP(staticWeaponInit); +PREP(staticWeaponInit_unloadExtraMags); diff --git a/addons/csw/XEH_postInit.sqf b/addons/csw/XEH_postInit.sqf new file mode 100644 index 0000000000..69137296c5 --- /dev/null +++ b/addons/csw/XEH_postInit.sqf @@ -0,0 +1,26 @@ +#include "script_component.hpp" + +GVAR(vehicleMagCache) = call CBA_fnc_createNamespace; + +["ace_settingsInitialized", { + TRACE_3("settingsInit",GVAR(defaultAssemblyMode),GVAR(handleExtraMagazines),GVAR(ammoHandling)); + ["StaticWeapon", "init", LINKFUNC(staticWeaponInit), true, [], true] call CBA_fnc_addClassEventHandler; +}] 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 new file mode 100644 index 0000000000..6ecb2a0c2f --- /dev/null +++ b/addons/csw/XEH_preInit.sqf @@ -0,0 +1,14 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +#include "initSettings.sqf" + +GVAR(initializedStaticTypes) = []; + +ADDON = true; + diff --git a/addons/medical_statemachine/XEH_postInit.sqf b/addons/csw/XEH_preStart.sqf similarity index 56% rename from addons/medical_statemachine/XEH_postInit.sqf rename to addons/csw/XEH_preStart.sqf index 421c54b49f..022888575e 100644 --- a/addons/medical_statemachine/XEH_postInit.sqf +++ b/addons/csw/XEH_preStart.sqf @@ -1 +1,3 @@ #include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/csw/config.cpp b/addons/csw/config.cpp new file mode 100644 index 0000000000..9478e7e798 --- /dev/null +++ b/addons/csw/config.cpp @@ -0,0 +1,24 @@ +#include "script_component.hpp" +#include "script_config_macros_csw.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {"ace_csw_carryTripod", "ace_csw_staticATWeapon"}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_interaction"}; + author = ECSTRING(common,ACETeam); + authors[] = {"TCVM"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "Cfg3den.hpp" +#include "CfgEventHandlers.hpp" +#include "CfgVehicles.hpp" +#include "CfgWeapons.hpp" +#include "CfgMagazines.hpp" +#include "CfgMagazineGroups.hpp" + diff --git a/addons/csw/data/model.cfg b/addons/csw/data/model.cfg new file mode 100644 index 0000000000..7adabdac10 --- /dev/null +++ b/addons/csw/data/model.cfg @@ -0,0 +1,69 @@ +class CfgSkeletons { + class Default { + isDiscrete = 1; + skeletonInherit = ""; + skeletonBones[] = {}; + }; + class ACE_CSW_Tripod_Skeleton: Default {}; + class ACE_CSW_M3_Tripod_Skeleton: Default {}; + class ace_csw_tripod_ags30_Skeleton: Default {}; + class ace_csw_tripod_kord_Skeleton: Default {}; + class ace_csw_tripod_m122_Skeleton: Default {}; + class ace_csw_tripod_m220_Skeleton: Default {}; + class ace_csw_tripod_spg9_Skeleton: Default {}; + class ACE_CSW_WeaponBag_Skeleton: Default {}; + class ACE_CSW_mortarBaseplate_Skeleton: Default {}; +}; +class CfgModels { + class Default { + sectionsInherit = ""; + sections[] = {}; + skeletonName = ""; + }; + class ACE_CSW_Tripod : Default { + sectionsInherit = ""; + sections[] = {}; + skeletonName = "ACE_CSW_Tripod_Skeleton"; + }; + class ACE_CSW_M3_Tripod : Default { + sectionsInherit = ""; + sections[] = {}; + skeletonName = "ACE_CSW_M3_Tripod_Skeleton"; + }; + class ace_csw_tripod_ags30 : Default { + sectionsInherit = ""; + sections[] = {}; + skeletonName = "ace_csw_tripod_ags30_Skeleton"; + }; + class ace_csw_tripod_kord : Default { + sectionsInherit = ""; + sections[] = {}; + skeletonName = "ace_csw_tripod_kord_Skeleton"; + }; + class ace_csw_tripod_m122 : Default { + sectionsInherit = ""; + sections[] = {}; + skeletonName = "ace_csw_tripod_m122_Skeleton"; + }; + class ace_csw_tripod_m220 : Default { + sectionsInherit = ""; + sections[] = {}; + skeletonName = "ace_csw_tripod_m220_Skeleton"; + }; + class ace_csw_tripod_spg9 : Default { + sectionsInherit = ""; + sections[] = {}; + skeletonName = "ace_csw_tripod_spg9_Skeleton"; + }; + class ACE_CSW_Bag: Default { + sectionsInherit = ""; + sections[] = {}; + skeletonName = "ACE_CSW_WeaponBag_Skeleton"; + }; + class ACE_CSW_mortarBaseplate: Default { + sectionsInherit = ""; + sections[] = {}; + skeletonName = "ACE_CSW_mortarBaseplate_Skeleton"; + }; +}; + diff --git a/addons/csw/dev/checkStaticWeapons.sqf b/addons/csw/dev/checkStaticWeapons.sqf new file mode 100644 index 0000000000..6ad8985b98 --- /dev/null +++ b/addons/csw/dev/checkStaticWeapons.sqf @@ -0,0 +1,76 @@ +#define DEBUG_MODE_FULL +#include "\z\ace\addons\csw\script_component.hpp" + +// Dev only function to search for weapons used by static weapons +// and check if their magazinese are compatible +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("------ Checking static weapons inheritance ------"); +private _explicitBases = []; +private _inherited = []; +{ + private _config = _x; + private _configEnabled = (getNumber (_config >> "ace_csw" >> "enabled")) == 1; + if (_configEnabled) then { + private _configExplicit = (count configProperties [_config, "configName _x == 'ace_csw'", false]) == 1; + if (_configExplicit) then { + _explicitBases pushBack (configName _config); + _inherited pushBack []; + } else { + if ((getNumber (_config >> "scope")) < 2) exitWith {}; + private _parent = inheritsFrom _config; + while {isClass _parent} do { + private _className = configName _parent; + private _index = _explicitBases findIf {_className == _x}; + if (_index > -1) exitWith { + (_inherited select _index) pushBack (configName _config); + }; + _parent = inheritsFrom _parent; + }; + }; + }; +} forEach _staticWeaponConfigs; +{ + INFO_2("%1 inherited by %2",_x,_inherited select _forEachIndex); +} forEach _explicitBases; + + + + +INFO("------ Logging static magazines with no carry version -------"); +private _hash = [] call CBA_fnc_hashCreate; +// private _logAll = true; // logs all possible weapon magazines (even if not used in a static weapon) +private _logAll = false; +{ + private _vehicleType = configName _x; + private _turretConfig = [_vehicleType, [0]] call CBA_fnc_getTurret; + private _weapons = getArray (_turretConfig >> "weapons"); + private _loadedMags = getArray (_turretConfig >> "magazines"); + { + private _weapMags = getArray (configFile >> "CfgWeapons" >> _x >> "magazines"); + { + private _xMag = _x; + private _groups = "getNumber (_x >> _xMag) == 1" configClasses (configFile >> QGVAR(groups)); + private _carryMag = configName (_groups param [0, configNull]); + if ((_carryMag == "") && {_logAll || {_xMag in _loadedMags}}) then { + private _vehs = [_hash, _xMag] call CBA_fnc_hashGet; + if (isNil "_vehs") then {_vehs = [];}; + if (_xMag in _loadedMags) then { + _vehs pushBack _vehicleType; + }; + [_hash, _xMag, _vehs] call CBA_fnc_hashSet; + }; + } forEach _weapMags; + } forEach _weapons; +} forEach _staticWeaponConfigs; + +[_hash, { + //IGNORE_PRIVATE_WARNING ["_key", "_value"]; + INFO_2("[%1] has no carry varient - Used in %2",_key,_value); +}] call CBA_fnc_hashEachPair; + +INFO("------ End -------"); diff --git a/addons/csw/functions/fnc_aceRearmGetCarryMagazines.sqf b/addons/csw/functions/fnc_aceRearmGetCarryMagazines.sqf new file mode 100644 index 0000000000..ac64f636e8 --- /dev/null +++ b/addons/csw/functions/fnc_aceRearmGetCarryMagazines.sqf @@ -0,0 +1,50 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Helper function for ace_rearm; Gets magazines that should be loaded by csw + * + * Arguments: + * 0: Vehicle + * 1: Specific Turret or pass bool to check all turrets (default: true) + * + * Return Value: + * [0: compatible veh mags, 1: carry mags] + * + * Example: + * [cursorObject, [0]] call ace_csw_fnc_aceRearmGetCarryMagazines + * + * Public: No + */ + +params ["_vehicle", ["_targetTurret", true, [[], true]]]; + +if (!(_vehicle isKindOf "StaticWeapon")) exitWith { [[],[]] }; // limit to statics for now +// Assembly mode: [0=disabled, 1=enabled, 2=enabled&unload, 3=default] +if ((GVAR(ammoHandling) == 0) && {!([false, true, true, GVAR(defaultAssemblyMode)] select (_vehicle getVariable [QGVAR(assemblyMode), 3]))}) exitWith { [[],[]] }; + +private _turretMagsCSW = []; +private _allCarryMags = []; +{ + private _turretPath = _x; + if ((_targetTurret isEqualTo true) || {_turretPath isEqualTo _targetTurret}) then { + { + private _weapon = _x; + { + private _xMag = _x; + private _carryMag = GVAR(vehicleMagCache) getVariable _xMag; + if (isNil "_carryMag") then { + private _groups = "getNumber (_x >> _xMag) == 1" configClasses (configFile >> QGVAR(groups)); + _carryMag = configName (_groups param [0, configNull]); + GVAR(vehicleMagCache) setVariable [_x, _carryMag]; + TRACE_2("setting cache",_xMag,_carryMag); + }; + if (_carryMag != "") then { + _turretMagsCSW pushBackUnique _xMag; + _allCarryMags pushBackUnique _carryMag; + }; + } forEach ([_weapon] call CBA_fnc_compatibleMagazines); + } forEach (_vehicle weaponsTurret _turretPath); + }; +} forEach (allTurrets _vehicle); + +[_turretMagsCSW, _allCarryMags] diff --git a/addons/csw/functions/fnc_ai_handleFired.sqf b/addons/csw/functions/fnc_ai_handleFired.sqf new file mode 100644 index 0000000000..f85c74fd20 --- /dev/null +++ b/addons/csw/functions/fnc_ai_handleFired.sqf @@ -0,0 +1,96 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Initializes weapon to disable weapon disassembling + * + * Arguments: + * 0: Weapon + * + * Return Value: + * None + * + * Example: + * [weapon] call ace_csw_fnc_ai_handleFired + * + * Public: No + */ + +params ["_staticWeapon", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_gunner"]; +TRACE_8("firedEH:",_staticWeapon, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _gunner); + +if ((!local _gunner) || {[_gunner] call EFUNC(common,isPlayer)}) exitWith {}; +if (someAmmo _staticWeapon) exitWith {}; + +TRACE_2("need ammo",someAmmo _staticWeapon,magazinesAllTurrets _staticWeapon); + +private _turretPath = [_gunner] call EFUNC(common,getTurretIndex); +private _reloadSource = objNull; +private _reloadMag = ""; +private _reloadNeededAmmo = -1; + +// Find if there is anything we can reload with +{ + scopeName "findSource"; + private _xSource = _x; + + private _cswMagazines = []; + { + if (isClass (configFile >> QGVAR(groups) >> _x)) then { _cswMagazines pushBackUnique _x; }; + } forEach (if (_xSource isKindOf "CaManBase") then {magazines _x} else {magazineCargo _x}); + TRACE_2("",_xSource,_cswMagazines); + + private _compatibleMags = [_magazine] + ([_weapon] call CBA_fnc_compatibleMagazines); // Check current mag first + + { + private _xWeaponMag = _x; + { + if ((getNumber (configFile >> QGVAR(groups) >> _x >> _xWeaponMag)) == 1) then { + private _loadInfo = [_staticWeapon, _turretPath, _reloadMag, objNull] call FUNC(reload_canLoadMagazine); + if (_loadInfo select 0) then { + _reloadMag = _x; + _reloadSource = _xSource; + _reloadNeededAmmo = _loadInfo select 2; + TRACE_3("found mag",_reloadMag,_reloadSource,_x); + breakOut "findSource"; + }; + }; + } forEach _cswMagazines; + } forEach _compatibleMags; +} forEach ([_gunner] + (_staticWeapon nearEntities [["groundWeaponHolder", "ReammoBox_F"], 10])); +if (_reloadMag == "") exitWith {TRACE_1("could not find mag",_reloadMag);}; + +// Figure out what we can add from the magazines we have +private _bestAmmoToSend = -1; +{ + _x params ["_xMag", "_xAmmo"]; + TRACE_2("",_xMag,_xAmmo); + if (_xMag == _reloadMag) then { + if ((_bestAmmoToSend == -1) || {(_xAmmo > _bestAmmoToSend) && {_xAmmo <= _reloadNeededAmmo}}) then { + _bestAmmoToSend = _xAmmo; + }; + }; +} forEach (if (_reloadSource isKindOf "CaManBase") then {magazinesAmmo _reloadSource} else {magazinesAmmoCargo _reloadSource}); +TRACE_4("",_reloadSource,_reloadMag,_reloadNeededAmmo,_bestAmmoToSend); +if (_bestAmmoToSend == -1) exitWith {ERROR("No ammo");}; + +// Remove the mag from the source +if (_reloadSource isKindOf "CaManBase") then { + [_reloadSource, _reloadMag, _bestAmmoToSend] call EFUNC(common,removeSpecificMagazine); +} else { + [_reloadSource, _reloadMag, 1, _bestAmmoToSend] call CBA_fnc_removeMagazineCargo; +}; + +private _timeToLoad = 1; +if (!isNull(configFile >> "CfgVehicles" >> (typeOf _staticWeapon) >> QUOTE(ADDON) >> "ammoLoadTime")) then { + _timeToLoad = getNumber(configFile >> "CfgVehicles" >> (typeOf _staticWeapon) >> QUOTE(ADDON) >> "ammoLoadTime"); +}; + +TRACE_1("Reloading in progress",_timeToLoad); +[{ + params ["_staticWeapon", "_turretPath", "_gunner", "_reloadMag", "_bestAmmoToSend"]; + if ((!alive _staticWeapon) || {!alive _gunner} || {(_staticWeapon distance _gunner) > 10}) exitWith {TRACE_1("invalid state",_this);}; + + // Reload the static weapon + TRACE_5("calling addTurretMag event",_staticWeapon, _turretPath, _gunner, _reloadMag, _bestAmmoToSend); + [QGVAR(addTurretMag), _this] call CBA_fnc_globalEvent; +}, [_staticWeapon, _turretPath, _gunner, _reloadMag, _bestAmmoToSend], _timeToLoad] call CBA_fnc_waitAndExecute; diff --git a/addons/csw/functions/fnc_assemble_canDeployTripod.sqf b/addons/csw/functions/fnc_assemble_canDeployTripod.sqf new file mode 100644 index 0000000000..a890e746ea --- /dev/null +++ b/addons/csw/functions/fnc_assemble_canDeployTripod.sqf @@ -0,0 +1,21 @@ +#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_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 new file mode 100644 index 0000000000..b0659e2f01 --- /dev/null +++ b/addons/csw/functions/fnc_assemble_canDeployWeapon.sqf @@ -0,0 +1,25 @@ +#include "script_component.hpp" +/* + * Author: TCVM + * Checks if you can deploy a weapon on the tripod + * + * Arguments: + * 0: Target Tripod + * 0: Player + * + * Return Value: + * Wether or not you can deploy the weapon + * + * Example: + * [cursorObject, player] call ace_csw_fnc_assemble_canDeployWeapon + * + * Public: No + */ + +params ["_target", "_player", "", "_carryWeaponClassname"]; +if (isNil "_carryWeaponClassname") then { _carryWeaponClassname = secondaryWeapon _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))) != ""} + diff --git a/addons/csw/functions/fnc_assemble_canPickupTripod.sqf b/addons/csw/functions/fnc_assemble_canPickupTripod.sqf new file mode 100644 index 0000000000..a5cd0d5c0c --- /dev/null +++ b/addons/csw/functions/fnc_assemble_canPickupTripod.sqf @@ -0,0 +1,22 @@ +#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 new file mode 100644 index 0000000000..ef40e03b3c --- /dev/null +++ b/addons/csw/functions/fnc_assemble_canPickupWeapon.sqf @@ -0,0 +1,26 @@ +#include "script_component.hpp" +/* + * Author: TCVM + * If the CSW is mounted or in use this will not allow you to dismount the weapon + * + * Arguments: + * 0: Static Weapon + * + * Return Value: + * Can Dismount + * + * Example: + * [cursorObject] call ace_csw_fnc_assemble_canPickupWeapon + * + * Public: No + */ + +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} + diff --git a/addons/csw/functions/fnc_assemble_deployTripod.sqf b/addons/csw/functions/fnc_assemble_deployTripod.sqf new file mode 100644 index 0000000000..d1392f5bac --- /dev/null +++ b/addons/csw/functions/fnc_assemble_deployTripod.sqf @@ -0,0 +1,72 @@ +#include "script_component.hpp" +/* + * Author: TCVM + * Deploys the tripod + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * [player] call ace_csw_fnc_assemble_deployTripod + * + * Public: No + */ + +[{ + params ["_player"]; + TRACE_1("assemble_deployTripod",_player); + + // Remove the tripod from the launcher slot + private _secondaryWeaponClassname = secondaryWeapon _player; + _player removeWeaponGlobal (secondaryWeapon _player); + + private _onFinish = { + params ["_args"]; + _args params ["_player", "_secondaryWeaponClassname"]; + TRACE_2("deployTripod finish",_player,_secondaryWeaponClassname); + + private _tripodClassname = getText(configFile >> "CfgWeapons" >> _secondaryWeaponClassname >> QUOTE(ADDON) >> "deploy"); + + // Create a tripod + 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 (!GVAR(defaultAssemblyMode)) then { + TRACE_1("global disableVanillaAssembly event",_cswTripod); // handles it being assembled when setting is disabled + [QGVAR(disableVanillaAssembly), [_cswTripod]] call CBA_fnc_globalEvent; + }; + + private _posATL = _player getRelPos [2, 0]; + _posATL set [2, ((getPosATL _player) select 2) + 0.5]; + + _cswTripod setDir (direction _player); + _cswTripod setPosATL _posATL; + _cswTripod setVectorUp (surfaceNormal _posATL); + + [_player, "PutDown"] call EFUNC(common,doGesture); + + // drag after deploying + 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); + } else { + TRACE_1("cannot carry",_cswTripod); + }; + }; + }; + + private _onFailure = { + params ["_args"]; + _args params ["_player", "_secondaryWeaponClassname"]; + TRACE_2("deployTripod failure",_player,_secondaryWeaponClassname); + + _player addWeaponGlobal _secondaryWeaponClassname; + }; + + private _deployTime = getNumber(configFile >> "CfgWeapons" >> _secondaryWeaponClassname >> QUOTE(ADDON) >> "deployTime"); + [TIME_PROGRESSBAR(_deployTime), [_player, _secondaryWeaponClassname], _onFinish, _onFailure, localize LSTRING(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 new file mode 100644 index 0000000000..12b5938bb9 --- /dev/null +++ b/addons/csw/functions/fnc_assemble_deployWeapon.sqf @@ -0,0 +1,77 @@ +#include "script_component.hpp" +/* + * Author: TCVM + * Deploys the current CSW + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * [player] call ace_csw_fnc_assemble_deployWeapon + * + * Public: No + */ + +[{ + params ["_tripod", "_player", "", "_carryWeaponClassname"]; + if (isNil "_carryWeaponClassname") then { _carryWeaponClassname = secondaryWeapon _player }; + TRACE_3("assemble_deployWeapon_carryWeaponClassname",_tripod,_player,_carryWeaponClassname); + + private _tripodClassname = typeOf _tripod; + _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);}; + + TRACE_4("",_carryWeaponClassname,_tripodClassname,_assembledClassname,_deployTime); + + private _onFinish = { + params ["_args"]; + _args params ["_tripod", "_player", "_assembledClassname"]; + TRACE_3("deployWeapon finish",_tripod,_player,_assembledClassname); + + private _tripodPos = getPosATL _tripod; + private _tripodDir = getDir _tripod; + deleteVehicle _tripod; + + _tripodPos set [2, (_tripodPos select 2) + 0.1]; + // Delay a frame so tripod has a chance to be deleted + [{ + params ["_assembledClassname", "_tripodDir", "_tripodPos"]; + 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 + 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 setDir _tripodDir; + _csw setPosATL _tripodPos; + if ((_tripodPos select 2) < 0.5) then { + _csw setVectorUp (surfaceNormal _tripodPos); + }; + TRACE_2("csw placed",_csw,_assembledClassname); + }, [_assembledClassname, _tripodDir, _tripodPos]] call CBA_fnc_execNextFrame; + }; + + private _onFailure = { + params ["_args"]; + _args params ["", "_player", "", "_carryWeaponClassname"]; + TRACE_2("deployWeapon failure",_player,_carryWeaponClassname); + + _player addWeaponGlobal _carryWeaponClassname; + }; + + private _codeCheck = { + params ["_args"]; + _args params ["_tripod"]; + !isNull _tripod; + }; + + [TIME_PROGRESSBAR(_deployTime), [_tripod, _player, _assembledClassname, _carryWeaponClassname], _onFinish, _onFailure, localize LSTRING(AssembleCSW_progressBar), _codeCheck] call EFUNC(common,progressBar); +}, _this] call CBA_fnc_execNextFrame; + diff --git a/addons/csw/functions/fnc_assemble_deployWeaponModifier.sqf b/addons/csw/functions/fnc_assemble_deployWeaponModifier.sqf new file mode 100644 index 0000000000..b1b89d8f09 --- /dev/null +++ b/addons/csw/functions/fnc_assemble_deployWeaponModifier.sqf @@ -0,0 +1,28 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Modifies interaction for deploying weapon + * + * Arguments: + * 0: Target + * 1: Player + * 2: Args + * 3: Action Data + * + * Return Value: + * None + * + * Example: + * [cursorObject, player, [], []] call ace_csw_fnc_assemble_deployWeaponModifier + * + * Public: No + */ + +params ["_target", "_player", "", "_actionData"]; + +private _carryWeaponClassname = secondaryWeapon _player; +private _assembleTo = (getText(configFile >> "CfgWeapons" >> _carryWeaponClassname >> QUOTE(ADDON) >> "assembleTo" >> (typeOf _target))); +private _icon = getText (configFile >> "CfgVehicles" >> _assembleTo >> "picture"); +TRACE_2("",_assembleTo,_icon); + +_actionData set [2, _icon]; diff --git a/addons/csw/functions/fnc_assemble_pickupTripod.sqf b/addons/csw/functions/fnc_assemble_pickupTripod.sqf new file mode 100644 index 0000000000..0167254795 --- /dev/null +++ b/addons/csw/functions/fnc_assemble_pickupTripod.sqf @@ -0,0 +1,47 @@ +#include "script_component.hpp" +/* + * Author: TCVM + * Picks up the tripod and adds it to the player launcher slot + * + * Arguments: + * 0: Tripod + * 1: Unit + * + * Return Value: + * None + * + * Example: + * [tripod, player] call ace_csw_fnc_assemble_pickupTripod + * + * Public: No + */ + +[{ + params ["_tripod", "_player"]; + TRACE_2("assemble_pickupTripod",_tripod,_player); + + private _tripodClassname = getText(configFile >> "CfgVehicles" >> (typeof _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); + + deleteVehicle _tripod; + _player addWeaponGlobal _tripodClassname; + [_player, "PutDown"] call EFUNC(common,doGesture); + }; + + private _condition = { + params ["_args"]; + _args params ["_tripod", "_player"]; + + !(isNull _tripod) && { (secondaryWeapon _player) isEqualTo "" } + + }; + + TRACE_3("",_pickupTime,typeOf _tripod,_tripodClassname); + [TIME_PROGRESSBAR(_pickupTime), [_tripod, _player, _tripodClassname], _onFinish, {}, localize LSTRING(PickupTripod_progressBar), _condition] call EFUNC(common,progressBar); +}, _this] call CBA_fnc_execNextFrame; + diff --git a/addons/csw/functions/fnc_assemble_pickupWeapon.sqf b/addons/csw/functions/fnc_assemble_pickupWeapon.sqf new file mode 100644 index 0000000000..1b131d4a3b --- /dev/null +++ b/addons/csw/functions/fnc_assemble_pickupWeapon.sqf @@ -0,0 +1,96 @@ +#include "script_component.hpp" +/* + * Author: TCVM + * Dismounts the weapon from the tripod and drops its backpack beside + * + * Arguments: + * 0: Static Weapon + * + * Return Value: + * None + * + * Example: + * [weapon] call ace_csw_fnc_assemble_pickupWeapon + * + * Public: No + */ + +[{ + params ["_staticWeapon", "_player"]; + TRACE_2("assemble_pickupWeapon",_staticWeapon,_player); + + private _onDisassembleFunc = getText(configFile >> "CfgVehicles" >> (typeOf _staticWeapon) >> QUOTE(ADDON) >> "disassembleFunc"); + private _carryWeaponClassname = getText(configFile >> "CfgVehicles" >> (typeOf _staticWeapon) >> QUOTE(ADDON) >> "disassembleWeapon"); + private _turretClassname = getText(configFile >> "CfgVehicles" >> (typeOf _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);}; + // Turret classname can equal nothing if the deploy bag is the "whole" weapon. e.g Kornet, Metis, other ATGMs + if (!(_turretClassname isEqualTo "") && {!isClass (configFile >> "CfgVehicles" >> _turretClassname)}) exitWith {ERROR_1("bad turret classname [%1]",_turretClassname);}; + + 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 _weaponDir = getDir _staticWeapon; + + LOG("remove ammo"); + { + _x params ["_xMag", "", "_xAmmo"]; + + private _carryMag = GVAR(vehicleMagCache) getVariable _xMag; + if (isNil "_carryMag") then { + private _groups = "getNumber (_x >> _xMag) == 1" configClasses (configFile >> QGVAR(groups)); + _carryMag = configName (_groups param [0, configNull]); + GVAR(vehicleMagCache) setVariable [_xMag, _carryMag]; + TRACE_2("setting cache",_xMag,_carryMag); + }; + if ((_xAmmo > 0) && {_carryMag != ""}) then { + TRACE_2("Removing ammo",_xMag,_carryMag); + [_player, _carryMag, _xAmmo] call FUNC(reload_handleReturnAmmo); + }; + } forEach (magazinesAllTurrets _staticWeapon); + + if !(_turretClassname isEqualTo "") then { + private _cswTripod = createVehicle [_turretClassname, [0, 0, 0], [], 0, "NONE"]; + // Delay a frame so weapon has a chance to be deleted + [{ + params ["_cswTripod", "_weaponDir", "_weaponPos"]; + _cswTripod setDir _weaponDir; + _cswTripod setPosATL _weaponPos; + _cswTripod setVelocity [0, 0, -0.05]; + _cswTripod setVectorUp (surfaceNormal _weaponPos); + }, [_cswTripod, _weaponDir, _weaponPos]] call CBA_fnc_execNextFrame; + [_cswTripod, _staticWeapon] call (missionNamespace getVariable _onDisassembleFunc); + }; + + [{ + params ["_player", "_weaponPos", "_carryWeaponClassname"]; + if ((alive _player) && {(secondaryWeapon _player) == ""}) exitWith { + _player addWeapon _carryWeaponClassname; + }; + 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]; + _weaponHolder addWeaponCargoGlobal [_carryWeaponClassname, 1]; + }, [_player, _weaponPos, _carryWeaponClassname]] call CBA_fnc_execNextFrame; + + LOG("delete weapon"); + deleteVehicle _staticWeapon; + + LOG("end"); + }; + + private _condition = { + params ["_args"]; + _args params ["_staticWeapon"]; + ((crew _staticWeapon) isEqualTo []) && (alive _staticWeapon) + }; + + [TIME_PROGRESSBAR(_pickupTime), [_staticWeapon, _player, _carryWeaponClassname, _turretClassname, _onDisassembleFunc], _onFinish, {}, localize LSTRING(DisassembleCSW_progressBar), _condition] call EFUNC(common,progressBar); +}, _this] call CBA_fnc_execNextFrame; + diff --git a/addons/csw/functions/fnc_canGetIn.sqf b/addons/csw/functions/fnc_canGetIn.sqf new file mode 100644 index 0000000000..92b05b1c2c --- /dev/null +++ b/addons/csw/functions/fnc_canGetIn.sqf @@ -0,0 +1,28 @@ +#include "script_component.hpp" +/* + * Author: TCVM + * Checks if the player can get in the weapon + * + * Arguments: + * 0: Static Weapon + * + * Return Value: + * None + * + * Example: + * [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 +}; + +params ["_staticWeapon"]; + +alive _staticWeapon +&& {!(alive (gunner _staticWeapon))} +&& {(locked _staticWeapon) < 2} +&& {0.3 < ((vectorUp _staticWeapon) select 2)} diff --git a/addons/csw/functions/fnc_getIn.sqf b/addons/csw/functions/fnc_getIn.sqf new file mode 100644 index 0000000000..338d17e03e --- /dev/null +++ b/addons/csw/functions/fnc_getIn.sqf @@ -0,0 +1,24 @@ +#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_proxyWeapon.sqf b/addons/csw/functions/fnc_proxyWeapon.sqf new file mode 100644 index 0000000000..3e47fddadd --- /dev/null +++ b/addons/csw/functions/fnc_proxyWeapon.sqf @@ -0,0 +1,44 @@ +#include "script_component.hpp" +/* + * Author: Brandon (TCVM), PabstMirror + * Handles the use of proxy weapons to fix engine-reload times + * + * Arguments: + * 0: Weapon + * 1: Turret + * 2: Proxy weapon needed + * 2: Weapon should be emptied + * + * Return Value: + * None + * + * Example: + * [weapon, [0], true, false] call ace_csw_fnc_proxyWeapon + * + * Public: No + */ + +params ["_staticWeapon", "_turret", "_needed", "_emptyWeapon"]; +TRACE_4("proxyWeapon",_staticWeapon,_turret,_needed,_emptyWeapon); + +if (_staticWeapon getVariable [format [QGVAR(proxyHandled_%1), _turret], false]) exitWith { TRACE_1("already handled",typeOf _staticWeapon); }; + +private _typeOf = typeOf _staticWeapon; +private _proxyWeapon = getText(configFile >> "CfgVehicles" >> _typeOf >> "ace_csw" >> "proxyWeapon"); + +TRACE_2("",_typeOf,_proxyWeapon); +if (_proxyWeapon == "") exitWith {}; + +private _currentWeapon = (_staticWeapon 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); + _needed = _proxyWeapon != ""; +}; +if (!_needed) exitWith { TRACE_2("not needed",_needed,_proxyWeapon); }; + +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]; diff --git a/addons/csw/functions/fnc_reload_actionsLoad.sqf b/addons/csw/functions/fnc_reload_actionsLoad.sqf new file mode 100644 index 0000000000..c5e7a3b574 --- /dev/null +++ b/addons/csw/functions/fnc_reload_actionsLoad.sqf @@ -0,0 +1,56 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Gets sub actions for what the player can load into the static weapon + * + * Arguments: + * 0: Static Weapon + * 1: Player + * + * Return Value: + * Actions + * + * Example: + * [cursorObject, player] call ace_csw_fnc_reload_actionsLoad + * + * Public: No + */ + +params ["_vehicle", "_player"]; + +private _actions = []; +private _loadableMagazines = [_vehicle, _player] call FUNC(reload_getLoadableMagazines); + +private _statement = { + params ["_target", "_player", "_params"]; + _params params ["_carryMag", "_turretPath"]; + + [_target, _turretPath, _carryMag, _player] call FUNC(reload_loadMagazine); +}; + +private _condition = { + params ["_target", "_player", "_params"]; + _params params ["_carryMag", "_turretPath"]; + + ([_target, _turretPath, _carryMag, _player] call FUNC(reload_canLoadMagazine)) select 0 +}; + +{ + _x params ["_carryMag", "_turretPath", "_loadInfo"]; + _loadInfo params ["", "", "", "_isBeltLinking"]; + + private _displayName = getText (configFile >> "CfgMagazines" >> _carryMag >> "displayName"); + private _picture = getText (configFile >> "CfgMagazines" >> _carryMag >> "picture"); + private _text = if (_isBeltLinking) then { + format [localize LSTRING(actionLink), _displayName]; + } else { + format [localize LSTRING(loadX), _displayName]; + }; + + private _action = [format ["load_%1", _forEachIndex], _text, _picture, _statement, _condition, {}, _x] call EFUNC(interact_menu,createAction); + _actions pushBack [_action, [], _vehicle]; +} forEach _loadableMagazines; + +TRACE_1("loadActions",count _actions); +_actions + diff --git a/addons/csw/functions/fnc_reload_actionsUnload.sqf b/addons/csw/functions/fnc_reload_actionsUnload.sqf new file mode 100644 index 0000000000..34b77b3c6b --- /dev/null +++ b/addons/csw/functions/fnc_reload_actionsUnload.sqf @@ -0,0 +1,81 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Gets sub actions for what the player can load into 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(configFile >> "CfgVehicles" >> (typeOf _target) >> QUOTE(ADDON) >> "ammoUnloadTime")) then { + _timeToUnload = getNumber(configFile >> "CfgVehicles" >> (typeOf _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 = []; + +// 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 = GVAR(vehicleMagCache) getVariable _xMag; + + if (isNil "_carryMag") then { + private _groups = "getNumber (_x >> _xMag) == 1" configClasses (configFile >> QGVAR(groups)); + _carryMag = configName (_groups param [0, configNull]); + GVAR(vehicleMagCache) setVariable [_xMag, _carryMag]; + TRACE_2("setting cache",_xMag,_carryMag); + }; + if (_carryMag == "") exitWith {}; + + private _displayName = getText (configFile >> "CfgMagazines" >> _carryMag >> "displayName"); + private _text = format [LLSTRING(unloadX), _displayName]; + private _picture = getText (configFile >> "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_canLoadMagazine.sqf b/addons/csw/functions/fnc_reload_canLoadMagazine.sqf new file mode 100644 index 0000000000..505c920333 --- /dev/null +++ b/addons/csw/functions/fnc_reload_canLoadMagazine.sqf @@ -0,0 +1,59 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror & TCVM + * Tests if unit can load a magazine into a static weapon. + * + * Arguments: + * 0: Static Weapon + * 1: Turret Path + * 2: Carryable Magazine + * 3: Player + * + * Return Value: + * [CanLoad, LoadedMag, AmmoNeeded, IsBeltLinking] + * + * Example: + * [cursorObject, [0], "ACE_csw_100Rnd_127x99_mag_red", player] call ace_csw_fnc_reload_canLoadMagazine + * + * Public: No + */ + +params ["_vehicle", "_turret", "_carryMag", ["_unit", objNull]]; +// TRACE_4("reload_canLoadMagazine",_vehicle,_turret,_carryMag,_unit); + +// Handle disassembled or deleted +if (!alive _vehicle) exitWith { [false, "", -1, false] }; +// Verify unit has carry magazine +if ((!isNull _unit) && {((_vehicle distance _unit) > 5) || {((magazines _unit) findIf {_x == _carryMag}) == -1}}) exitWith { [false, "", -2, false] }; + +private _desiredAmmo = getNumber (configFile >> "CfgVehicles" >> (typeOf _vehicle) >> QUOTE(ADDON) >> "desiredAmmo"); +if (_desiredAmmo == 0) then { _desiredAmmo = 100; }; +private _ammoNeeded = _desiredAmmo min getNumber (configFile >> "CfgMagazines" >> _carryMag >> "count"); // assume it needs full carry mag +private _loadedMag = ""; +private _isBeltLinking = false; + +scopeName "main"; +{ + _x params ["_xMag", "_xTurret", "_xAmmo"]; + if (_xTurret isEqualTo _turret) then { + if (_loadedMag != "") exitWith { [false, _loadedMag, -3, false] breakOut "main"; }; // Exit if static has multiple mags + _loadedMag = _xMag; + if (_xAmmo > 0) then { + // There is a magazine with ammo loaded in the turret (are there any multi-muzzle static weapons??), see if we can add to this mag + if (getNumber (configFile >> QGVAR(groups) >> _carryMag >> _xMag) != 1) exitWith { + [false, _loadedMag, -4, false] breakOut "main"; // Carry mag cannot be added to existing vehicle mag (e.g. red to green tracers) + }; + if (getNumber (configFile >> "CfgMagazines" >> _carryMag >> "ACE_isBelt") == 0) exitWith { + [false, _loadedMag, -5, false] breakOut "main"; // Non-linkable mag loaded, can't add any more + }; + private _maxMagazineAmmo = _desiredAmmo min getNumber (configFile >> "CfgMagazines" >> _xMag >> "count"); + if (_xAmmo >= _maxMagazineAmmo) exitWith { + [false, _loadedMag, -6, false] breakOut "main"; // Already at capicity + }; + _ammoNeeded = _maxMagazineAmmo - _xAmmo; + _isBeltLinking = true; + }; + }; +} forEach (magazinesAllTurrets _vehicle); + +[true, _loadedMag, _ammoNeeded, _isBeltLinking] diff --git a/addons/csw/functions/fnc_reload_canUnloadMagazine.sqf b/addons/csw/functions/fnc_reload_canUnloadMagazine.sqf new file mode 100644 index 0000000000..2ce6b6e591 --- /dev/null +++ b/addons/csw/functions/fnc_reload_canUnloadMagazine.sqf @@ -0,0 +1,33 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Tests if unit can unload a magazine from a static weapon. + * + * Arguments: + * 0: Static Weapon + * 1: Turret Path + * 2: Player + * 3: Carryable Magazine + * 4: Vehicle Magazine + * + * Return Value: + * + * + * Example: + * [cursorTarget, [0], player, "ACE_csw_100Rnd_127x99_mag_red", "200Rnd_127x99_mag_Tracer_Red"] call ace_csw_fnc_reload_canUnloadMagazine + * + * Public: No + */ + +params ["_vehicle", "_turretPath", "_unit", "_carryMag", "_vehMag"]; + +// handle disassembled or deleted +if ((!alive _vehicle) || {(_vehicle distance _unit) > 5}) exitWith {false}; + +private _return = false; +{ + _x params ["_xMag", "_xTurret", "_xAmmo"]; + if ((_xMag == _vehMag) && {_xTurret isEqualTo _turretPath} && {_xAmmo > 0}) exitWith { _return = true }; +} forEach (magazinesAllTurrets _vehicle); + +_return diff --git a/addons/csw/functions/fnc_reload_getLoadableMagazines.sqf b/addons/csw/functions/fnc_reload_getLoadableMagazines.sqf new file mode 100644 index 0000000000..8e6f3ce500 --- /dev/null +++ b/addons/csw/functions/fnc_reload_getLoadableMagazines.sqf @@ -0,0 +1,52 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Gets magazines that the player is carrying that can be loaded into the static weapon + * + * Arguments: + * 0: Vehicle + * 1: Player + * + * Return Value: + * Mags + * [Carry Magazine , Turret Path , Ammo Needed ] + * + * Example: + * [cursorObject, player] call ace_csw_fnc_reload_getLoadableMagazines + * + * Public: No + */ + +params ["_vehicle", "_player"]; + +private _carriedMagazines = []; + +{ + if (isClass (configFile >> QGVAR(groups) >> _x)) then { + _carriedMagazines pushBackUnique _x; + }; +} forEach (magazines _player); + +if (_carriedMagazines isEqualTo []) exitWith { [] }; // fast exit if no carry mags + +private _loadInfo = []; +private _return = []; +// Go through turrets and find weapons that we could reload +{ + private _turretPath = _x; + { + private _weapon = _x; + { + private _carryMag = _x; + private _carryGroup = configFile >> QGVAR(groups) >> _carryMag; + { + if (((getNumber (_carryGroup >> _x)) == 1) && {_loadInfo = [_vehicle, _turretPath, _carryMag, _player] call FUNC(reload_canLoadMagazine); _loadInfo select 0}) exitWith { + _return pushBack [_carryMag, _turretPath, _loadInfo]; + }; + } forEach ([_weapon] call CBA_fnc_compatibleMagazines); + } forEach _carriedMagazines; + } forEach (_vehicle weaponsTurret _turretPath); +} forEach (allTurrets _vehicle); +// Note: these nested forEach's looks terrible, but most only have one element + +_return diff --git a/addons/csw/functions/fnc_reload_getVehicleMagazine.sqf b/addons/csw/functions/fnc_reload_getVehicleMagazine.sqf new file mode 100644 index 0000000000..b6265852c9 --- /dev/null +++ b/addons/csw/functions/fnc_reload_getVehicleMagazine.sqf @@ -0,0 +1,45 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Finds the best vehicle magazines to create from a carryable magazine for a given weapon. + * + * Arguments: + * 0: Weapon + * 1: Magazine that is carryable + * + * Return Value: + * Vehicle Magazine + * + * Example: + * [cursorObject, [0], "ace_csw_100Rnd_127x99_mag"] call ace_csw_fnc_reload_getVehicleMagazine + * + * Public: No + */ + +params ["_vehicle", "_turret", "_carryMag"]; +TRACE_3("reload_getVehicleMagazine",_vehicle,_turret,_carryMag); + +private _carryGroupCfg = configFile >> QGVAR(groups) >> _carryMag; +private _desiredAmmo = getNumber (configFile >> "CfgVehicles" >> (typeOf _vehicle) >> QUOTE(ADDON) >> "desiredAmmo"); +if (_desiredAmmo == 0) then { _desiredAmmo = 100; }; + +private _bestMag = "#"; +private _bestMagCount = -1; + +{ + private _weapon = _x; + { + if ((getNumber (_carryGroupCfg >> _x)) == 1) then { + private _xAmmo = getNumber (configFile >> "CfgMagazines" >> _x >> "ammo"); + if (((_xAmmo >= _bestMagCount) && {_bestMagCount < _desiredAmmo}) || {(_xAmmo >= _desiredAmmo) && {_xAmmo < _bestMagCount}}) then { + _bestMag = _x; + _bestMagCount = _xAmmo; + }; + }; + } forEach (getArray (configFile >> "CfgWeapons" >> _weapon >> "magazines")); +} forEach (_vehicle weaponsTurret _turret); +TRACE_3("best fit",_desiredAmmo,_bestMag,_bestMagCount); + +if (_bestMag == "#") then { ERROR_1("veh mag not found for %1",_carryMag); }; + +_bestMag diff --git a/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf b/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf new file mode 100644 index 0000000000..841192864a --- /dev/null +++ b/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf @@ -0,0 +1,66 @@ +#include "script_component.hpp" +/* + * Author: TCVM, PabstMirror + * Handles adding ammo to a turret + * Called from a global event but only runs where turret is local + * + * Arguments: + * 0: Static Weapon + * 1: Turret Path + * 2: Unit doing action + * 3: Vehicle Magazine + * 4: Ammo in magazine + * + * Return Value: + * None + * + * Example: + * [cursorTarget, [0], player, "200Rnd_127x99_mag_Tracer_Red", 70] call ace_csw_fnc_reload_handleAddTurretMag + * + * Public: No + */ + +params ["_vehicle", "_turret", "_unit", "_carryMag" ,"_ammoRecieved"]; +TRACE_5("reload_handleAddTurretMag",_vehicle,_turret,_unit,_carryMag,_ammoRecieved); + +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); + +private _ammoRemaining = _ammoRecieved; +if (_canAdd) then { + private _ammoUsed = _neededAmmo min _ammoRecieved; + _ammoRemaining = _ammoRemaining - _ammoUsed; + + if (_isBeltLinking) then { + private _currentAmmo = _vehicle magazineTurretAmmo [_loadedMag, _turret]; + _currentAmmo = _currentAmmo + _ammoUsed; + TRACE_2("Setting mag ammo",_loadedMag,_currentAmmo); + // _vehicle setMagazineTurretAmmo [_loadedMag, _currentAmmo, _turret]; + + // 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); + _vehicle setAmmo [_weapon, _currentAmmo]; + private _currentAmmo = _vehicle magazineTurretAmmo [_loadedMag, _turret]; + if ((_weapon == "") || {_currentAmmo != _currentAmmo}) then { ERROR_1("failed to setAmmo - %1", _this); }; + + } else { + if (_loadedMag != "") then { + TRACE_1("Removing emtpy mag",_loadedMag); + _vehicle removeMagazinesTurret [_loadedMag, _turret]; + }; + [_vehicle, _turret, true, false] call FUNC(proxyWeapon); // Check if we need to add proxy weapon now + private _newMag = [_vehicle, _turret, _carryMag] call FUNC(reload_getVehicleMagazine); + TRACE_2("Adding new mag",_newMag,_ammoUsed); + _vehicle addMagazineTurret [_newMag, _turret, _ammoUsed]; + }; +}; + +if (_ammoRemaining > 0) then { + TRACE_3("Returning ammo",_unit,_carryMag,_ammoRemaining); + [QGVAR(returnAmmo), [_unit, _carryMag, _ammoRemaining], _unit] call CBA_fnc_targetEvent; +}; + diff --git a/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf b/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf new file mode 100644 index 0000000000..1e64bf82f5 --- /dev/null +++ b/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf @@ -0,0 +1,79 @@ +#include "script_component.hpp" +/* + * Author: TCVM + * Handles removing ammo from a turret + * Called from a global event but only runs where turret is local + * + * Arguments: + * 0: Static Weapon + * 1: Turret Path + * 2: Magainze Unit Can Carry + * 3: Magazine To Remove From Static + * 4: Unit to unload to + * + * Return Value: + * None + * + * Example: + * [cursorTarget, [0], "ACE_csw_100Rnd_127x99_mag_red", "500Rnd_127x99_mag_Tracer_Green", player] call ace_csw_fnc_reload_handleRemoveTurretMag + * + * Public: No + */ + +params ["_vehicle", "_turretPath", "_carryMag", "_vehMag", "_unit"]; +TRACE_6("removeTurretMag EH",_vehicle,_turretPath,_carryMag,_vehMag,_unit); + +TRACE_3("",local _vehicle, _vehicle turretLocal _turretPath,local _unit); +if (!(_vehicle turretLocal _turretPath)) exitWith {}; + +private _magsInWeapon = []; // Check how much ammo it has now: +{ + _x params ["_xMag", "_xTurret", "_xAmmo"]; + if ((_xMag == _vehMag) && {_xTurret isEqualTo _turretPath}) then { + _magsInWeapon pushBack _xAmmo; + }; +} forEach (magazinesAllTurrets _vehicle); +TRACE_1("",_magsInWeapon); + +// Remove any empty mags from start: +private _ammoInFirstMag = 0; +while {(!(_magsInWeapon isEqualTo [])) && {_ammoInFirstMag = _magsInWeapon deleteAt 0; (_ammoInFirstMag == 0)}} do { + TRACE_1("Removing empty mag",_ammoInFirstMag); + _vehicle removeMagazineTurret [_vehMag, _turretPath]; +}; +TRACE_2("",_magsInWeapon,_ammoInFirstMag); +if ((_magsInWeapon isEqualTo []) && {_ammoInFirstMag == 0}) exitWith {}; + +private _maxAmmo = getNumber (configFile >> "CfgMagazines" >> _carryMag >> "count"); +private _ammoRemoved = _ammoInFirstMag min _maxAmmo; +private _ammoLeft = _ammoInFirstMag - _ammoRemoved; + +if ((_magsInWeapon isEqualTo []) && {_ammoInFirstMag > _ammoRemoved}) then { + // Only one mag in gun, and we're just taking out a partial ammount (unlinking) + TRACE_2("Setting mag ammo",_ammoRemoved,_ammoLeft); + // _vehicle setMagazineTurretAmmo [_vehMag, _ammoLeft, _turretPath]; + + // setMagazineTurretAmmo is broken on split locality, use setAmmo for now + private _weapon = (_vehicle weaponsTurret _turretPath) param [0, ""]; + 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); }; + + +} else { + // Because of command limitations, we need to remove mags to change their ammo + // This will cause the gun to need to be reloaded if more than one is loaded (only a problem for non-assembly mode guns) + TRACE_2("Removing magazine",_ammoRemoved,_ammoLeft); + _vehicle removeMagazinesTurret [_vehMag, _turretPath]; + if (_ammoLeft > 0) then { + _magsInWeapon pushBack _ammoLeft; + TRACE_1("Re-adding partial",_ammoLeft); + }; + { + if (_x > 0) then { _vehicle addMagazineTurret [_vehMag, _turretPath, _x]; }; + } forEach _magsInWeapon; +}; + +TRACE_3("Returning ammo",_unit,_carryMag,_ammoRemoved); +[QGVAR(returnAmmo), [_unit, _carryMag, _ammoRemoved], _unit] call CBA_fnc_targetEvent; diff --git a/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf b/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf new file mode 100644 index 0000000000..1d288b863f --- /dev/null +++ b/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf @@ -0,0 +1,70 @@ +#include "script_component.hpp" +/* + * Author: TCVM and PabstMirror + * Handles returned ammo (either from unloading or leftovers from linking) + * + * Arguments: + * 0: Man or Vehicle + * 1: Carry Magazine + * 2: Ammo in magazine + * + * Return Value: + * None + * + * Example: + * [player, "ace_csw_100Rnd_127x99_mag", 70] call ace_csw_fnc_reload_handleReturnAmmo + * + * Public: No + */ + +params ["_unloadTo", "_carryMag", "_ammo"]; +TRACE_3("reload_handleReturnAmmo",_unloadTo,_carryMag,_ammo); + +private _carryMaxAmmo = getNumber (configFile >> "CfgMagazines" >> _carryMag >> "count"); +private _fullMagazines = floor (_ammo / _carryMaxAmmo); +private _bulletsRemaining = _ammo % _carryMaxAmmo; + +if (_unloadTo isKindOf "CaManBase") then { + while {(_fullMagazines > 0) && {_unloadTo canAdd _carryMag}} do { + _unloadTo addMagazine [_carryMag, _carryMaxAmmo]; + _fullMagazines = _fullMagazines - 1; + }; + if ((_bulletsRemaining > 0) && {_unloadTo canAdd _carryMag}) then { + _unloadTo addMagazine [_carryMag, _bulletsRemaining]; + _bulletsRemaining = 0; + }; +}; + +if ((_fullMagazines == 0) && {_bulletsRemaining == 0}) exitWith {}; + +// Try to use existing container +private _container = _unloadTo getVariable [QGVAR(container), objNull]; +if ((_container distance _unloadTo) > 4) then { _container = objNull; }; +if (isNull _container) then { + _container = (nearestObjects [_unloadTo, ["groundWeaponHolder"], 4]) param [0, objNull]; +}; + + +if (isNull _container) then { + // Create ground weapon holder container + private _weaponRelPos = _unloadTo getRelPos RELATIVE_DIRECTION(270); + _weaponRelPos set [2, ((getPosATL _unloadTo) select 2) + 0.05]; + _container = createVehicle ["groundWeaponHolder", [0, 0, 0], [], 0, "NONE"]; + // ToDo: Unload to ammo box?? + _unloadTo setVariable [QGVAR(container), _container, true]; + _container setDir random [0, 180, 360]; + _container setPosATL _weaponRelPos; + if ((_weaponRelPos select 2) < 0.5) then { + _container setVectorUp (surfaceNormal _weaponRelPos); + }; + TRACE_2("Creating NEW Container",_container,_weaponRelPos); +}; + +TRACE_3("adding to container",_container,_fullMagazines,_bulletsRemaining); + +if (_fullMagazines > 0) then { + _container addMagazineAmmoCargo [_carryMag, _fullMagazines, _carryMaxAmmo]; +}; +if (_bulletsRemaining > 0) then { + _container addMagazineAmmoCargo [_carryMag, 1, _bulletsRemaining]; +}; diff --git a/addons/csw/functions/fnc_reload_loadMagazine.sqf b/addons/csw/functions/fnc_reload_loadMagazine.sqf new file mode 100644 index 0000000000..25032a08f4 --- /dev/null +++ b/addons/csw/functions/fnc_reload_loadMagazine.sqf @@ -0,0 +1,66 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Loads a magazine into a static weapon from a magazine carried by the player. + * + * Arguments: + * 0: Vehicle + * 1: Turret + * 2: Unit Carried Magazine + * 3: Player + * + * Return Value: + * None + * + * Example: + * [cursorTarget, [0], "ACE_csw_100Rnd_127x99_mag_red", player] call ace_csw_fnc_reload_loadMagazine + * + * Public: No + */ + +params ["_vehicle", "_turret", "_carryMag", "_unit"]; +TRACE_4("loadMagazine",_vehicle,_turret,_carryMag,_unit); + +private _timeToLoad = 1; +if (!isNull(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> QUOTE(ADDON) >> "ammoLoadTime")) then { + _timeToLoad = getNumber(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> QUOTE(ADDON) >> "ammoLoadTime"); +}; + +private _displayName = format [localize LSTRING(loadX), getText (configFile >> "CfgMagazines" >> _carryMag >> "displayName")]; + +private _onFinish = { + (_this select 0) params ["_vehicle", "_turret", "_carryMag", "_unit"]; + TRACE_4("load progressBar finish",_vehicle,_turret,_carryMag,_unit); + + ([_vehicle, _turret, _carryMag, _unit] call FUNC(reload_canLoadMagazine)) params ["", "", "_neededAmmo", ""]; + if (_neededAmmo <= 0) exitWith { ERROR_1("Can't load ammo - %1",_this); }; + + // Figure out what we can add from the magazines we have + private _bestAmmoToSend = -1; + { + _x params ["_xMag", "_xAmmo"]; + if (_xMag == _carryMag) then { + if ((_bestAmmoToSend == -1) || {(_xAmmo > _bestAmmoToSend) && {_xAmmo <= _neededAmmo}}) then { + _bestAmmoToSend = _xAmmo; + }; + }; + } forEach (magazinesAmmo _unit); + + if (_bestAmmoToSend == -1) exitWith {ERROR_2("No ammo [%1 - %2]?",_xMag,_bestAmmoToSend);}; + [_unit, _carryMag, _bestAmmoToSend] call EFUNC(common,removeSpecificMagazine); + if (_bestAmmoToSend == 0) exitWith {}; + + TRACE_5("calling addTurretMag event",_vehicle,_turret,_unit,_carryMag,_bestAmmoToSend); + [QGVAR(addTurretMag), [_vehicle, _turret, _unit, _carryMag, _bestAmmoToSend]] call CBA_fnc_globalEvent; +}; + + +[ +TIME_PROGRESSBAR(_timeToLoad), +[_vehicle, _turret, _carryMag, _unit], +_onFinish, +{TRACE_1("load progressBar fail",_this);}, +_displayName, +{((_this select 0) call FUNC(reload_canLoadMagazine)) select 0}, +["isNotInside"] +] call EFUNC(common,progressBar); diff --git a/addons/csw/functions/fnc_staticWeaponInit.sqf b/addons/csw/functions/fnc_staticWeaponInit.sqf new file mode 100644 index 0000000000..4ce86f3c49 --- /dev/null +++ b/addons/csw/functions/fnc_staticWeaponInit.sqf @@ -0,0 +1,95 @@ +#include "script_component.hpp" +/* + * Author: Brandon (TCVM) + * Initializes weapon to disable weapon disassembling + * + * Arguments: + * 0: Weapon + * + * Return Value: + * None + * + * Example: + * [weapon] call ace_csw_fnc_staticWeaponInit + * + * Public: No + */ + +params ["_staticWeapon"]; +private _typeOf = typeOf _staticWeapon; +private _configEnabled = (getNumber (configFile >> "CfgVehicles" >> _typeOf >> "ace_csw" >> "enabled")) == 1; +private _assemblyConfig = _configEnabled && {(getText (configFile >> "CfgVehicles" >> _typeOf >> "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)]; +}; + +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 (configFile >> "CfgVehicles" >> _typeOf >> 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 new file mode 100644 index 0000000000..bd73df878c --- /dev/null +++ b/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf @@ -0,0 +1,83 @@ +#include "script_component.hpp" +/* + * Author: Brandon (TCVM), PabstMirror + * Dumps ammo to container + * + * Arguments: + * 0: Weapon + * 1: Using advanced assembly + * + * Return Value: + * None + * + * Example: + * [cursorObject, false] call ace_csw_fnc_staticWeaponInit_unloadExtraMags + * + * Public: No + */ + +params ["_staticWeapon", "_assemblyMode", "_emptyWeapon"]; +TRACE_3("staticWeaponInit_unloadExtraMags",_staticWeapon,_assemblyMode,_emptyWeapon); +if (!_assemblyMode) exitWith {}; + +private _desiredAmmo = getNumber (configFile >> "CfgVehicles" >> (typeOf _staticWeapon) >> QUOTE(ADDON) >> "desiredAmmo"); +private _storeExtraMagazines = GVAR(handleExtraMagazines); +if (_emptyWeapon) then { + _desiredAmmo = 0; + _storeExtraMagazines = false; +}; +TRACE_3("settings",_emptyWeapon,_desiredAmmo,_storeExtraMagazines); + +private _magsToRemove = []; +private _loadedMagazineInfo = []; +private _containerMagazineClassnames = []; +private _containerMagazineCount = []; + +{ + _x params ["_xMag", "_xTurret", "_xAmmo"]; + + private _carryMag = GVAR(vehicleMagCache) getVariable _xMag; + if (isNil "_carryMag") then { + private _groups = "getNumber (_x >> _xMag) == 1" configClasses (configFile >> QGVAR(groups)); + _carryMag = configName (_groups param [0, configNull]); + GVAR(vehicleMagCache) setVariable [_xMag, _carryMag]; + TRACE_2("setting cache",_xMag,_carryMag); + }; + if (_carryMag != "") then { + if ((_desiredAmmo > 0) && {_loadedMagazineInfo isEqualTo []}) then { + private _loadedMagAmmo = _desiredAmmo min _xAmmo; + _loadedMagazineInfo = [_xMag, _xTurret, _loadedMagAmmo]; + _xAmmo = _xAmmo - _loadedMagAmmo; + TRACE_1("",_loadedMagAmmo); + }; + if (_xAmmo > 0) then { + _magsToRemove pushBackUnique [_xMag, _xTurret]; + private _index = _containerMagazineClassnames find _carryMag; + if (_index < 0) then { + _index = _containerMagazineClassnames pushBack _carryMag; + _containerMagazineCount pushBack 0; + }; + _containerMagazineCount set [_index, (_containerMagazineCount select _index) + _xAmmo]; + }; + } else { + if ((_xMag select [0,4]) != "fake") then { WARNING_1("Unable to unload [%1] - No matching carry mag",_xMag); }; + }; +} forEach (magazinesAllTurrets _staticWeapon); + + +TRACE_1("Remove all loaded magazines",_magsToRemove); +{ + _staticWeapon removeMagazinesTurret _x; + if ((_loadedMagazineInfo select [0,2]) isEqualTo _x) then { + TRACE_1("Re-add the starting mag",_loadedMagazineInfo); + _staticWeapon addMagazineTurret _loadedMagazineInfo; + }; +} forEach _magsToRemove; + + +if (_storeExtraMagazines) then { + TRACE_1("saving extra mags to container",_containerMagazineCount); + { + [_staticWeapon, _x, _containerMagazineCount select _forEachIndex] call FUNC(reload_handleReturnAmmo); + } forEach _containerMagazineClassnames; +}; diff --git a/addons/csw/functions/script_component.hpp b/addons/csw/functions/script_component.hpp new file mode 100644 index 0000000000..7e8eaa8954 --- /dev/null +++ b/addons/csw/functions/script_component.hpp @@ -0,0 +1 @@ +#include "\z\ace\addons\csw\script_component.hpp" diff --git a/addons/csw/initSettings.sqf b/addons/csw/initSettings.sqf new file mode 100644 index 0000000000..28397a6e9b --- /dev/null +++ b/addons/csw/initSettings.sqf @@ -0,0 +1,53 @@ +// CBA Settings [ADDON: ace_csw]: + +private _categoryArray = [format ["ACE %1", localize LSTRING(DisplayName)]]; + +[ + QGVAR(defaultAssemblyMode), "CHECKBOX", + [LSTRING(defaultAssemblyMode_displayName), LSTRING(defaultAssemblyMode_description)], + _categoryArray, + false, // default value + true, // isGlobal + {[QGVAR(defaultAssemblyMode), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_settings_fnc_init; + +[ + QGVAR(handleExtraMagazines), "CHECKBOX", + [LSTRING(handleExtraMagazines_displayName), LSTRING(handleExtraMagazines_description)], + _categoryArray, + true, // default value + true, // isGlobal + {[QGVAR(handleExtraMagazines), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_settings_fnc_init; + +[ + QGVAR(ammoHandling), "LIST", + [LSTRING(ammoHandling_displayName), LSTRING(ammoHandling_description)], + _categoryArray, + [[0, 1, 2], [LELSTRING(common,Disabled), LELSTRING(common,playerOnly), LELSTRING(common,playersAndAI)], 2], // [_values, _valueTitles, _defaultIndex] + true, // isGlobal + {[QGVAR(ammoHandling), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_settings_fnc_init; + +[ + QGVAR(progressBarTimeCoefficent), "SLIDER", + [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 +] call CBA_settings_fnc_init; + +[ + 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 +] call CBA_settings_fnc_init; diff --git a/addons/csw/script_component.hpp b/addons/csw/script_component.hpp new file mode 100644 index 0000000000..29521039f2 --- /dev/null +++ b/addons/csw/script_component.hpp @@ -0,0 +1,28 @@ +#define COMPONENT csw +#define COMPONENT_BEAUTIFIED Crew-Served Weapons +#include "\z\ace\addons\main\script_mod.hpp" + +// #define FAST_PROGRESSBARS +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_CSW + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_CSW + #define DEBUG_SETTINGS DEBUG_SETTINGS_CSW +#endif + +#include "\z\ace\addons\main\script_macros.hpp" + + +#define DISTANCE_FROM_GUN 1.5 +#define RELATIVE_DIRECTION(direction) [DISTANCE_FROM_GUN, direction] + +#ifdef FAST_PROGRESSBARS + #define TIME_PROGRESSBAR(X) ((X) * 0.075) +#else + #define TIME_PROGRESSBAR(X) ((X) * GVAR(progressBarTimeCoefficent)) +#endif diff --git a/addons/csw/script_config_macros_csw.hpp b/addons/csw/script_config_macros_csw.hpp new file mode 100644 index 0000000000..1a0e1b3be5 --- /dev/null +++ b/addons/csw/script_config_macros_csw.hpp @@ -0,0 +1,15 @@ +#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 new file mode 100644 index 0000000000..090c302ef5 --- /dev/null +++ b/addons/csw/stringtable.xml @@ -0,0 +1,309 @@ + + + + + Crew Served Weapons + Crew Served Weapons (CSW) + + + Place Tripod + Montar Tripé + + + Disassemble + Rozložit + Démonter + %1 demontieren + Disassemblare + Złóż + Desmontar + Разобрать + Desmonta + + + Get In + Nastup + Embarquer + Einsteigen + A bordo + Wsiadać + Entrar + Войти + Entrar + + + Load %1 + Lade %1 + Load %1 + Nabít %1 + Load %1 + Załaduj %1 + Load %1 + Загрузить %1 + Load %1 + Carregar %1 + + + Unload %1 + Entlade %1 + Unload %1 + Vytáhnout zásobník z %1 + Unload %1 + Rozładuj %1 + Unload %1 + Разгрузить %1 + Unload %1 + Descarregar %1 + + + Link %1 + Conectar %1 + + + Advanced assembly + Montagem Avançada + + + Use ace for Assemble/Disassemble of supported static weapons. Loaded ammo is reduced to a single magazine. + Usar o ACE para Montar/Desmontar armas estáticas suportadas. Munição carregada é reduzida para um único carregador. + + + Save extra ammo + Economizar munição extra + + + Store extra magazines next to static weapon + Carregar munições extras próximo à arma estática + + + Ammo handling + Manipulação de Munições + + + Allow loading and unloading magazines + Permite carregamento e descarregamento de munições + + + Interaction Time Coefficent + Coeficiente de tempo para a interação + + + Scales time required to assemble and reload static weapons + Escala o tempo requerido para montar e recarregar armas estáticas. + + + Drag tripods after deploying + Arrastar tripés após montar + + + After deploying a tripod, start dragging it to a precise location + Assim que montar um tripé, automaticamente começa a arrastá-lo para um posicionamento mais preciso + + + Pickup Tripod + Carregar Tripé + + + Mount Weapon + Montar Arma + + + Disassembling Gun... + Desmontando Arma... + + + Assembling Gun... + Montando Arma... + + + Picking Up Tripod... + Carregando Tripé... + + + Placing Tripod... + Montando Tripé... + + + Enable CSW + Ativar CSW + + + Enables Crew Served ability on this weapon + Ativar funções de CSW nessa arma + + + Enabled and Leave Weapon Empty + Ativado e deixar arma vazia + + + Tripod + Trépied + Trípode + Treppiede + Trójnóg + Dreibein + Üçayak + Tripé + + + [CSW] Static Mini-Spike Launcher (AT) + [CSW] Lançador Estático - Mini-Spike (AT) + + + [CSW] Static Mini-Spike Launcher (AA) + [CSW] Lançador Estático - Mini-Spike (AA) + + + [CSW] Static XM312 Gun + [CSW] Arma Estática - XM312 + + + [CSW] Static XM312 Gun (Autonomous) + [CSW] Arma Estática - XM312 (Autônoma) + + + [CSW] Static XM307 Gun + [CSW] Arma Estática - XM307 + + + [CSW] Static XM307 Gun (Autonomous) + [CSW] Arma Estática - XM307 (Autônoma) + + + [CSW] 12.7x108mm HMG Belt + [CSW] Cinto de Munição - 12.7x108mm HMG + + + [CSW] 12.7x99mm HMG Belt + [CSW] Cinto de Munição - 12.7x99mm HMG + + + [CSW] 12.7x99mm Tracer HMG Belt (Red) + [CSW] Cinto de Munição - 12.7x99mm HMG (Traçante Vermelho) + + + [CSW] 12.7x99mm Tracer HMG Belt (Green) + [CSW] Cinto de Munição - 12.7x99mm HMG (Traçante Verde) + + + [CSW] 12.7x99mm Tracer HMG Belt (Yellow) + [CSW] Cinto de Munição - 12.7x99mm HMG (Traçante Amarelo) + + + [CSW] 20mm Grenade GMG Belt + [CSW] Cinto de Munição - Granada 20mm GMG + + + M3 Tripod + M3 Tripé + + + [CSW] 6P57 Deployable Tripod + [CSW] 6P57 Tripé Ajustável + + + [CSW] 6P57 Deployable Tripod (Low) + [CSW] 6P57 Tripé Ajustável (Baixo) + + + [CSW] M220 Deployable Tripod + [CSW] M220 Tripé Ajustável + + + [CSW] SAG-30 Deployable Tripod + [CSW] SAG-30 Tripé Ajustável + + + 6P57 Tripod + Tripé 6P57 + + + SAG-30 Tripod + Tripe SAG-30 + + + M220 Tripod + Tripé M220 + + + [CSW] M3 Deployable Tripod + [CSW] M3 Tripe Ajustável + + + [CSW] M3 Deployable Tripod (Low) + [CSW] M3 Tripe Ajustável (Baixo) + + + [CSW] Mortar Baseplate + [CSW] Placa base de Morteiro + + + Mortar Baseplate + Placa base de Morteiro + + + [CSW] Mk6 Mortar Tube + [CSW] Tubo de Morteiro - Mk6 + + + [CSW] M252 Tube Bag + [CSW] Tubo de Morteiro - M252 + + + [CSW] M2 Gun Bag + [CSW] Bolsa de Arma - M2 + + + [CSW] MK19 Gun Bag + [CSW] Bolsa de Arma - MK19 + + + [CSW] BGM-71 TOW Launcher Bag + [CSW] Bolsa de Lançador - BGM-71 TOW + + + [CSW] DSHK Gun Bag + [CSW] Bolsa de Arma - DSHK + + + [CSW] 2B14 Tube Bag + [CSW] Bolsa de Arma - 2B14 + + + [CSW] NSV Gun Bag + [CSW] Bolsa de Arma - NSV + + + [CSW] KORD Gun Bag + [CSW] Bolsa de Arma - KORD + + + [CSW] AGS-30 Gun Bag + [CSW] Bolsa de Arma - AGS-30 + + + [CSW] 9k115 Metis Launcher Bag + [CSW] Bolsa de Arma - 9k115 Metis + + + [CSW] 9m113 Kornet Launcher + [CSW] Bolsa de Arma - 9m113 Kornet + + + SPG-9 Tripod + Tripé SPG-9 + + + [CSW] SPG-9 Deployable Tripod + [CSW] SPG-9 Tripe Ajustável (Baixo) + + + [CSW] SPG-9 Launcher Bag + [CSW] Bolsa de Lançador - SPG-9 + + + [CSW] SPG-9M Launcher Bag + [CSW] Bolsa de Lançador - SPG-9M + + + diff --git a/addons/dogtags/stringtable.xml b/addons/dogtags/stringtable.xml index 45d2e827d7..07654c97c6 100644 --- a/addons/dogtags/stringtable.xml +++ b/addons/dogtags/stringtable.xml @@ -13,6 +13,7 @@ Piastrina 兵籍牌 兵籍牌 + Dog Tag Check Dog Tag @@ -26,6 +27,7 @@ Controlla Piastrina 檢查兵籍牌 检查兵籍牌 + Verificar Dog Tag Check @@ -39,6 +41,7 @@ Controlla 檢查 检查 + Verificar Take @@ -52,6 +55,7 @@ Prendi 拿取 拿取 + Pegar Dogtag taken from %1... @@ -65,6 +69,7 @@ Piastrina presa da %1... 從%1身上拿取兵籍牌... 从%1身上拿取兵籍牌... + Dogtag pego de %1... Somebody else has already taken the dogtag... @@ -78,13 +83,17 @@ Qualcun altro ha già preso la piastrina... 已經有人把他的兵籍牌拿走了... 已经有人把他的兵籍牌拿走了... + Alguém já pegou essa dogtag... Onscreen display for checking dogtags + Anzeige um Hundemarke zu überprüfen 在畫面中顯示檢查兵籍牌 確認中のドッグタグを画面上で表示します Display 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/CfgMovesMaleSdr.hpp b/addons/dragging/CfgMovesMaleSdr.hpp new file mode 100644 index 0000000000..715765679f --- /dev/null +++ b/addons/dragging/CfgMovesMaleSdr.hpp @@ -0,0 +1,13 @@ +class CfgMovesMaleSdr: CfgMovesBasic { + class InjuredMovedBase; + class AgonyBaseRfl; + + class States { + class AcinPknlMstpSnonWnonDnon_AcinPercMrunSnonWnonDnon: InjuredMovedBase { + speed = -10; // 1/10 + }; + class AinjPfalMstpSnonWrflDnon_carried_Up: AgonyBaseRfl { + speed = -10; // 1/10 + }; + }; +}; diff --git a/addons/dragging/config.cpp b/addons/dragging/config.cpp index c3f5d0dd84..188f3916f2 100644 --- a/addons/dragging/config.cpp +++ b/addons/dragging/config.cpp @@ -17,3 +17,4 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgVehicles.hpp" #include "CfgMovesBasic.hpp" +#include "CfgMovesMaleSdr.hpp" diff --git a/addons/dragging/functions/fnc_startCarry.sqf b/addons/dragging/functions/fnc_startCarry.sqf index 729fec2a4e..a52afd1c27 100644 --- a/addons/dragging/functions/fnc_startCarry.sqf +++ b/addons/dragging/functions/fnc_startCarry.sqf @@ -48,7 +48,7 @@ if (_target isKindOf "CAManBase") then { [_unit, "AcinPknlMstpSnonWnonDnon_AcinPercMrunSnonWnonDnon", 2, true] call EFUNC(common,doAnimation); [_target, "AinjPfalMstpSnonWrflDnon_carried_Up", 2, true] call EFUNC(common,doAnimation); - _timer = CBA_missionTime + 15; + _timer = CBA_missionTime + 10; } else { diff --git a/addons/dragon/$PBOPREFIX$ b/addons/dragon/$PBOPREFIX$ new file mode 100644 index 0000000000..41f191d39b --- /dev/null +++ b/addons/dragon/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\dragon \ No newline at end of file diff --git a/addons/dragon/ACE_GuidanceConfig.hpp b/addons/dragon/ACE_GuidanceConfig.hpp new file mode 100644 index 0000000000..18cc5dd9fe --- /dev/null +++ b/addons/dragon/ACE_GuidanceConfig.hpp @@ -0,0 +1,11 @@ +class EGVAR(missileguidance,AttackProfiles) { + class DRAGON { + name = CSTRING(dragonName); + visualName = CSTRING(dragonName); + description = CSTRING(dragonName); + + onFired = QFUNC(onFired); + functionName = QFUNC(attackProfile_DRAGON); + }; +}; + diff --git a/addons/dragon/CfgAmmo.hpp b/addons/dragon/CfgAmmo.hpp new file mode 100644 index 0000000000..033239013f --- /dev/null +++ b/addons/dragon/CfgAmmo.hpp @@ -0,0 +1,147 @@ +class CfgAmmo { + class ammo_Penetrator_Base; + class M_Scalpel_AT; + class Rocket_03_AP_F; + + class GVAR(penetrator_super): ammo_Penetrator_Base { + caliber = 60; + warheadName = "HEAT"; + hit = 460; + fuseDistance = 75; + }; + + class GVAR(dragonBase): Rocket_03_AP_F { + EGVAR(frag,skip) = 1; + scope = 1; + aiAmmoUsageFlags = "128+512"; + model = QPATHTOF(models\dragon.p3d); + maxSpeed = 200; + thrust = 300; + initTime = 0.151; + thrustTime = 0; + sideAirFriction = 0.05; + effectsMissile = "missile2"; + effectFlare = ""; + airFriction = 0.5; + fuseDistance = 75; + whistleDist = 2; + + hit = 100; + indirectHit = 9; + indirectHitRange = 1; + explosive = 0.8; + timeToLive = 60; + cost = 500; + simulationStep = 0.005; + maxControlRange = 1500; + + class ace_missileguidance { + minDeflection = 0; + maxDeflection = 0; + incDeflection = 0; + + canVanillaLock = 0; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + seekLastTargetPos = 0; + seekerAngle = 30; + seekerAccuracy = 1; + + seekerMinRange = 65; + seekerMaxRange = 1000; + + correctionDistance = 30; + missileLeadDistance = 0; + offsetFromCrosshair[] = { 0, 0, 0 }; + + serviceInterval = 0.33; // how many seconds between pops + serviceCharges = 32; // how many charges are in this missile + serviceChargeAcceleration = 6.5; + dragonSpeed = 100; // meters per second + + defaultAttackProfile = "DRAGON"; + attackProfiles[] = {"DRAGON"}; + }; + }; + + class GVAR(super) : GVAR(dragonBase) { + submunitionAmmo = QGVAR(penetrator_super); + submunitionDirectionType = "SubmunitionModelDirection"; + submunitionInitSpeed = 1000; + submunitionParentSpeedCoef = 0; + submunitionInitialOffset[] = { 0, 0, -0.2 }; + + class ace_missileguidance { + enabled = 1; + + // Guidance type for munitions + defaultSeekerType = "SACLOS"; + seekerTypes[] = { "SACLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + seekLastTargetPos = 0; + seekerAngle = 30; + seekerAccuracy = 1; + + seekerMinRange = 30; + seekerMaxRange = 1500; + + correctionDistance = 30; + missileLeadDistance = 0; + + serviceInterval = 0.33; // how many seconds between pops + serviceCharges = 60; // how many charges are in this missile + serviceChargeAcceleration = 6.5; + dragonSpeed = 100; // meters per second + + defaultAttackProfile = "DRAGON"; + attackProfiles[] = {"DRAGON"}; + }; + }; + + class ShellBase; + class GVAR(serviceCharge) : ShellBase { + hit = 1; + indirectHit = 2; + indirectHitRange = 1; + typicalSpeed = 100; + explosive = 1; + cost = 300; + model = "\A3\Weapons_F\empty.p3d"; + airFriction = 0; + timeToLive = 1; + explosionTime = 0.001; + soundFly[] = {"",1,1}; + soundEngine[] = {"",1,4}; + CraterEffects = ""; + explosionEffects = QGVAR(serviceExplosion); + hitarmor[] = {"soundDefault1", 1}; + hitbuilding[] = {"soundDefault1", 1}; + hitconcrete[] = {"soundDefault1", 1}; + hitdefault[] = {"soundDefault1", 1}; + hitfoliage[] = {"soundDefault1", 1}; + hitglass[] = {"soundDefault1", 1}; + hitglassarmored[] = {"soundDefault1", 1}; + hitgroundhard[] = {"soundDefault1", 1}; + hitgroundsoft[] = {"soundDefault1", 1}; + hitiron[] = {"soundDefault1", 1}; + hitman[] = {"soundDefault1", 1}; + hitmetal[] = {"soundDefault1", 1}; + hitmetalplate[] = {"soundDefault1", 1}; + hitplastic[] = {"soundDefault1", 1}; + hitrubber[] = {"soundDefault1", 1}; + hitwood[] = {"soundDefault1", 1}; + sounddefault1[] = {QPATHTOF(sounds\service_charge.wss), 56.2341, 1, 1800}; + soundHit[] = {QPATHTOF(sounds\service_charge.wss),56.23413,1,1800}; + multiSoundHit[] = {"soundDefault1", 1}; + }; +}; + diff --git a/addons/dragon/CfgEventHandlers.hpp b/addons/dragon/CfgEventHandlers.hpp new file mode 100644 index 0000000000..0d3301d6e0 --- /dev/null +++ b/addons/dragon/CfgEventHandlers.hpp @@ -0,0 +1,17 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_FILE(XEH_preStart)); + }; +}; + +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_FILE(XEH_preInit)); + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_FILE(XEH_postInit)); + }; +}; diff --git a/addons/dragon/CfgMagazines.hpp b/addons/dragon/CfgMagazines.hpp new file mode 100644 index 0000000000..e4b59a9304 --- /dev/null +++ b/addons/dragon/CfgMagazines.hpp @@ -0,0 +1,16 @@ +class CfgMagazines { + class 1Rnd_GAA_missiles; + class GVAR(super) : 1Rnd_GAA_missiles { + sound[] = {}; + soundFly[] = {}; + soundHit[] = {}; + model = QPATHTOF(models\dragon.p3d); + ammo = QGVAR(super); + initSpeed = 120; + scope = 1; + displayName = CSTRING(dragonName); + displayNameShort = CSTRING(dragonName); + descriptionShort = CSTRING(dragonDescription); + }; +}; + diff --git a/addons/dragon/CfgVehicles.hpp b/addons/dragon/CfgVehicles.hpp new file mode 100644 index 0000000000..faac05bbe9 --- /dev/null +++ b/addons/dragon/CfgVehicles.hpp @@ -0,0 +1,151 @@ +class CfgVehicles { + class LandVehicle; + class StaticWeapon: LandVehicle { + class Turrets; + class MainTurret; + class ACE_Actions { + class ACE_MainActions {}; + }; + }; + + class StaticATWeapon: StaticWeapon {}; + + class GVAR(staticBase): StaticATWeapon { + scope = 1; + author = ECSTRING(common,ACETeam); + displayname = CSTRING(dragonName); + side = 1; + faction = "BLU_F"; + crew = "B_soldier_f"; + model = QPATHTOF(models\ace_m47_static.p3d); + picture = "\A3\Static_F_Gamma\data\UI\gear_StaticTurret_AT_CA.paa"; + UiPicture = "\A3\Static_F_Gamma\data\UI\gear_StaticTurret_AT_CA.paa"; + icon = "\A3\Static_F_Gamma\data\UI\map_StaticTurret_AT_CA.paa"; + threat[] = {0.7,1.0,0.1}; + cost = 150000; + class Damage { + tex[] = {}; + mat[] = { + "a3\static_f_gamma\data\staticturret_01.rvmat", + "a3\static_f_gamma\data\staticturret_01_damage.rvmat", + "a3\static_f_gamma\data\staticturret_01_destruct.rvmat", + "a3\static_f_gamma\data\staticturret_02.rvmat", + "a3\static_f_gamma\data\staticturret_02_damage.rvmat", + "a3\static_f_gamma\data\staticturret_02_destruct.rvmat", + "a3\weapons_f_beta\launchers\titan\data\titan_launcher.rvmat", + "a3\weapons_f_beta\launchers\titan\data\titan_launcher_damage.rvmat", + "a3\weapons_f_beta\launchers\titan\data\titan_launcher_destruct.rvmat", + "a3\weapons_f_beta\launchers\titan\data\titan_mtube.rvmat", + "a3\weapons_f_beta\launchers\titan\data\titan_mtube_damage.rvmat", + "a3\weapons_f_beta\launchers\titan\data\titan_mtube_destruct.rvmat" + }; + }; + class Turrets: Turrets { + class MainTurret: MainTurret { + optics = 1; + turretInfoType = "RscWeaponEmpty"; + gunnerOpticsModel = QPATHTOF(models\optics_m47.p3d); + minElev = -30; + maxElev = 20; + weapons[] = { QGVAR(dummyStatic) }; + magazines[] = { QGVAR(super) }; + + gunnerAction = "gunner_static_low01"; + gunnergetInAction = ""; + gunnergetOutAction = ""; + + discreteDistance[] = {}; + discreteDistanceInitIndex = 0; + + displayName = CSTRING(dragonName); + + class ViewOptics { + initAngleX = 0; + minAngleX = -30; + maxAngleX = 30; + initAngleY = 5; + minAngleY = -100; + maxAngleY = 100; + initFov = 0.055; + minFov = 0.055; // 6 degree FOV + maxFov = 0.055; + visionMode[] = {"Normal"}; + thermalMode[] = {0}; + }; + gunnerRightHandAnimName = "OtocHlaven_shake"; + gunnerLeftHandAnimName = "OtocHlaven_shake"; + gunBeg = "spice rakety"; + gunEnd = "konec rakety"; + memoryPointGunnerOptics = "look"; + }; + }; + class AnimationSources { + class rest_rotate { + source="user"; + animPeriod=0.00001; + initPhase=-0.35; + maxValue="3.60"; + minValue="-3.60"; + }; + class optic_hide { + source="user"; + animPeriod=0.0001; + initPhase=1; + maxValue="1"; + minValue="0"; + }; + class missile_hide { + source="user"; + animPeriod=0.0001; + initPhase=0; + maxValue="1"; + minValue="0"; + }; + }; + soundGetOut[] = {"A3\sounds_f\dummysound",0.001,1,5}; + soundGetIn[] = {"A3\sounds_f\dummysound",0.00031622776,1,5}; + armorStructural = 10.0; + + class ACE_CSW { + disassembleTo = QGVAR(super); + }; + + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + displayName = CSTRING(dragonName); + class GVAR(pickUp) { + displayName = ECSTRING(csw,Pickup_displayName); + condition = QUOTE(call FUNC(canPickupTripod)); + statement = QUOTE(call EFUNC(csw,assemble_pickupTripod)); + }; + class GVAR(attachSight) { + displayName = CSTRING(attachSight); + condition = QUOTE(call FUNC(sightCanAttach)); + statement = QUOTE(call FUNC(sightAttach)); + icon = QPATHTOF(data\m47_daysight_interaction_attach.paa); + }; + class GVAR(detachSight) { + displayName = CSTRING(detachSight); + condition = QUOTE(call FUNC(sightCanDetach)); + statement = QUOTE(call FUNC(sightDetach)); + icon = QPATHTOF(data\m47_daysight_interaction_detach.paa); + }; + }; + }; + + }; + + class GVAR(staticAssembled): GVAR(staticBase) { + scope = 2; + class AnimationSources: AnimationSources { + class optic_hide: optic_hide { + initPhase = 0; + }; + }; + class Turrets: Turrets { + class MainTurret: MainTurret { + weapons[] = { QGVAR(superStatic) }; + }; + }; + }; +}; diff --git a/addons/dragon/CfgWeapons.hpp b/addons/dragon/CfgWeapons.hpp new file mode 100644 index 0000000000..9cb58e2c1f --- /dev/null +++ b/addons/dragon/CfgWeapons.hpp @@ -0,0 +1,90 @@ +class CfgWeapons { + class launch_Titan_base; + class Launcher_Base_F; + class missiles_titan; + class Binocular; + class Default; + class missiles_titan_static: missiles_titan { + class WeaponSlotsInfo; + }; + class launch_Titan_F: launch_Titan_base { + class WeaponSlotsInfo; + }; + + class GVAR(super): launch_Titan_F { + model = QPATHTOF(models\ace_m47_magazine.p3d); + picture = QPATHTOF(data\m47_dragon_item_ca.paa); + magazines[] = {}; + displayName = CSTRING(dragonNameCarry); // add [CSW] prefix to make it clearer in arsenal that this is a deployable weapon + descriptionShort = CSTRING(dragonDescription); + scope = 2; + + class ACE_CSW { + type = "mount"; + deployTime = 2; + pickupTime = 2; + deploy = QGVAR(staticBase); + }; + + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 253; + }; + modes[] = {}; + }; + + class GVAR(superStatic): missiles_titan_static { + EGVAR(overpressure,angle) = 90; + EGVAR(overpressure,range) = 30; + EGVAR(overpressure,damage) = 0.85; + + initSpeed = 120; + + displayName = CSTRING(dragonName); + descriptionShort = CSTRING(dragonDescription); + magazines[] = { QGVAR(super) }; + }; + + // need a weapon in order to rotate turret + class GVAR(dummyStatic): Default { + cursor = ""; + cursorAim = ""; + scope = 1; + displayName = CSTRING(dragonName); + reloadTime = 0; + canLock = 0; + optics = 0; + enableAttack = 0; + }; + + class GVAR(sight): Binocular { + displayName = CSTRING(sightName); + model = QPATHTOF(models\ace_m47_optic.p3d); + picture = QPATHTOF(data\m47_daysight_item_ca.paa); + optics = 1; + weaponInfoType = "RscWeaponEmpty"; + modelOptics = QPATHTOF(models\optics_m47); + reloadaction = ""; + showSwitchAction = 1; + useAsBinocular = 1; + uipicture = ""; + descriptionShort = CSTRING(sightDescription); + ace_disposable = 0; + magazines[] = {}; + type = 4096; + opticsPPEffects[] = {"OpticsCHAbera1","OpticsBlur1"}; + opticsZoomMin = 0.055; + opticsZoomMax = 0.055; + scope = 2; + class ACE_CSW { + type = "weapon"; + deployTime = 2; + pickupTime = 1; + class assembleTo { + GVAR(super_noSight) = QGVAR(super_sight); + }; + }; + class WeaponSlotsInfo { + mass = 68; + }; + }; +}; diff --git a/addons/dragon/README.md b/addons/dragon/README.md new file mode 100644 index 0000000000..84a82ad820 --- /dev/null +++ b/addons/dragon/README.md @@ -0,0 +1,12 @@ +ace_dragon +=================== + +Adds M47 Dragon Missile. + + +## Maintainers + +The people responsible for merging changes to this component or answering potential questions. + +- [Brandon-TCVM](https://github.com/TheCandianVendingMachine) + diff --git a/addons/dragon/XEH_PREP.hpp b/addons/dragon/XEH_PREP.hpp new file mode 100644 index 0000000000..148dff5cf6 --- /dev/null +++ b/addons/dragon/XEH_PREP.hpp @@ -0,0 +1,7 @@ +PREP(attackProfile_DRAGON); +PREP(canPickupTripod); +PREP(onFired); +PREP(sightAttach); +PREP(sightCanAttach); +PREP(sightCanDetach); +PREP(sightDetach); diff --git a/addons/dragon/XEH_postInit.sqf b/addons/dragon/XEH_postInit.sqf new file mode 100644 index 0000000000..0305fe772a --- /dev/null +++ b/addons/dragon/XEH_postInit.sqf @@ -0,0 +1,41 @@ +#include "script_component.hpp" + +[QGVAR(detachSight), LINKFUNC(sightDetach)] call CBA_fnc_addEventHandler; +[QGVAR(attachSight), LINKFUNC(sightAttach)] call CBA_fnc_addEventHandler; + +["vehicle", { + params ["","_vehicle"]; + TRACE_2("vehicle change",_vehicle,typeOf _vehicle); + if (!(_vehicle isKindOf QGVAR(staticBase))) exitWith {}; + + _vehicle animate ["rest_rotate", 0]; + + if (isNil QGVAR(pfID)) then {GVAR(pfID) = -1}; + [GVAR(pfID)] call CBA_fnc_removePerFrameHandler; + + private _lastView = cameraView; + if (!(_lastView in ["INTERNAL", "EXTERNAL"])) then { _lastView == "INTERNAL"; }; + + GVAR(pfID) = [{ + params ["_args"]; + (_this select 0) params ["_vehicle", "_lastView"]; + + if ((!alive _vehicle) || {!alive ACE_player} || {(vehicle ACE_player) != _vehicle}) exitWith { + TRACE_1("exiting PFEH",GVAR(pfID)); + [GVAR(pfID)] call CBA_fnc_removePerFrameHandler; + if ((alive _vehicle) && {!alive gunner _vehicle}) then { + TRACE_1("reseting rest rotate anim",_vehicle); + _vehicle animate ["rest_rotate", -0.35]; + }; + }; + + if (cameraView in ["INTERNAL", "EXTERNAL"]) then { + _args set [1, cameraView]; + } else { + if ((cameraOn == _vehicle) && {!(_vehicle getVariable [QGVAR(sightAttached), ((typeOf _vehicle) == QGVAR(staticAssembled))])}) then { + _vehicle switchCamera _lastView; + }; + }; + }, 0, [_vehicle, _lastView]] call CBA_fnc_addPerFrameHandler; + TRACE_1("started PFEH",GVAR(pfID)); +}, true] call CBA_fnc_addPlayerEventHandler; diff --git a/addons/dragon/XEH_preInit.sqf b/addons/dragon/XEH_preInit.sqf new file mode 100644 index 0000000000..29cc0a7f24 --- /dev/null +++ b/addons/dragon/XEH_preInit.sqf @@ -0,0 +1,10 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +ADDON = true; + diff --git a/addons/dragon/XEH_preStart.sqf b/addons/dragon/XEH_preStart.sqf new file mode 100644 index 0000000000..76b104a5bc --- /dev/null +++ b/addons/dragon/XEH_preStart.sqf @@ -0,0 +1,4 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" + diff --git a/addons/dragon/anim/M47.rtm b/addons/dragon/anim/M47.rtm new file mode 100644 index 0000000000..48f3dfc3c4 Binary files /dev/null and b/addons/dragon/anim/M47.rtm differ diff --git a/addons/dragon/anim/model.cfg b/addons/dragon/anim/model.cfg new file mode 100644 index 0000000000..6be7f511b5 --- /dev/null +++ b/addons/dragon/anim/model.cfg @@ -0,0 +1,119 @@ +class cfgSkeletons { + class OFP2_ManSkeleton { + isDiscrete = 0; + skeletonInherit = ""; + skeletonBones[] = { + "Pelvis","", + "Spine","Pelvis", + "Spine1","Spine", + "Spine2","Spine1", + "Spine3","Spine2", + "camera","Pelvis",// case has changed for arma3 + "weapon","Spine1", + "launcher","Spine1", + "Neck","Spine3", + "Neck1","Neck", + "Head","Neck1", //Head skeleton in hierarchy + //Left upper side + "LeftShoulder","Spine3", + "LeftArm","LeftShoulder", + "LeftArmRoll","LeftArm", + "LeftForeArm","LeftArmRoll", + "LeftForeArmRoll","LeftForeArm", + "LeftHand","LeftForeArmRoll", + "LeftHandRing","LeftHand", + "LeftHandRing1","LeftHandRing", + "LeftHandRing2","LeftHandRing1", + "LeftHandRing3","LeftHandRing2", + "LeftHandPinky1","LeftHandRing", + "LeftHandPinky2","LeftHandPinky1", + "LeftHandPinky3","LeftHandPinky2", + "LeftHandMiddle1","LeftHand", + "LeftHandMiddle2","LeftHandMiddle1", + "LeftHandMiddle3","LeftHandMiddle2", + "LeftHandIndex1","LeftHand", + "LeftHandIndex2","LeftHandIndex1", + "LeftHandIndex3","LeftHandIndex2", + "LeftHandThumb1","LeftHand", + "LeftHandThumb2","LeftHandThumb1", + "LeftHandThumb3","LeftHandThumb2", + //Right upper side + "RightShoulder","Spine3", + "RightArm","RightShoulder", + "RightArmRoll","RightArm", + "RightForeArm","RightArmRoll", + "RightForeArmRoll","RightForeArm", + "RightHand","RightForeArmRoll", + "RightHandRing","RightHand", + "RightHandRing1","RightHandRing", + "RightHandRing2","RightHandRing1", + "RightHandRing3","RightHandRing2", + "RightHandPinky1","RightHandRing", + "RightHandPinky2","RightHandPinky1", + "RightHandPinky3","RightHandPinky2", + "RightHandMiddle1","RightHand", + "RightHandMiddle2","RightHandMiddle1", + "RightHandMiddle3","RightHandMiddle2", + "RightHandIndex1","RightHand", + "RightHandIndex2","RightHandIndex1", + "RightHandIndex3","RightHandIndex2", + "RightHandThumb1","RightHand", + "RightHandThumb2","RightHandThumb1", + "RightHandThumb3","RightHandThumb2", + //Left lower side + "LeftUpLeg","Pelvis", + "LeftUpLegRoll","LeftUpLeg", + "LeftLeg","LeftUpLegRoll", + "LeftLegRoll","LeftLeg", + "LeftFoot","LeftLegRoll", + "LeftToeBase","LeftFoot", + //Right lower side + "RightUpLeg","Pelvis", + "RightUpLegRoll","RightUpLeg", + "RightLeg","RightUpLegRoll", + "RightLegRoll","RightLeg", + "RightFoot","RightLegRoll", + "RightToeBase","RightFoot", + //New facial features arma3 only + "Face_Hub","Head", + "Face_Jawbone","Face_Hub", + "Face_Jowl","Face_Jawbone", + "Face_chopRight","Face_Jawbone", + "Face_chopLeft","Face_Jawbone", + "Face_LipLowerMiddle","Face_Jawbone", + "Face_LipLowerLeft","Face_Jawbone", + "Face_LipLowerRight","Face_Jawbone", + "Face_Chin","Face_Jawbone", + "Face_Tongue","Face_Jawbone", + "Face_CornerRight","Face_Hub", + "Face_CheekSideRight","Face_CornerRight", + "Face_CornerLeft","Face_Hub", + "Face_CheekSideLeft","Face_CornerLeft", + "Face_CheekFrontRight","Face_Hub", + "Face_CheekFrontLeft","Face_Hub", + "Face_CheekUpperRight","Face_Hub", + "Face_CheekUpperLeft","Face_Hub", + "Face_LipUpperMiddle","Face_Hub", + "Face_LipUpperRight","Face_Hub", + "Face_LipUpperLeft","Face_Hub", + "Face_NostrilRight","Face_Hub", + "Face_NostrilLeft","Face_Hub", + "Face_Forehead","Face_Hub", + "Face_BrowFrontRight","Face_Forehead", + "Face_BrowFrontLeft","Face_Forehead", + "Face_BrowMiddle","Face_Forehead", + "Face_BrowSideRight","Face_Forehead", + "Face_BrowSideLeft","Face_Forehead", + "Face_Eyelids","Face_Hub", + "Face_EyelidUpperRight","Face_Hub", + "Face_EyelidUpperLeft","Face_Hub", + "Face_EyelidLowerRight","Face_Hub", + "Face_EyelidLowerLeft","Face_Hub", + "EyeLeft","Face_Hub", + "EyeRight","Face_Hub" + };// end of skeleton array + // location of pivot points (local axes) for hierarchical animation + pivotsModel="A3\anims_f\data\skeleton\SkeletonPivots.p3d"; + }; +}; + diff --git a/addons/dragon/config.cpp b/addons/dragon/config.cpp new file mode 100644 index 0000000000..78d836936e --- /dev/null +++ b/addons/dragon/config.cpp @@ -0,0 +1,42 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_hot","ace_csw"}; + author = ECSTRING(common,ACETeam); + authors[] = {"Brandon (TCVM)"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "ACE_GuidanceConfig.hpp" +#include "CfgEventHandlers.hpp" +#include "CfgWeapons.hpp" +#include "CfgMagazines.hpp" +#include "CfgAmmo.hpp" +#include "CfgVehicles.hpp" + +class GVAR(serviceExplosion) { + class Light1 { + simulation = "light"; + type = "GrenadeExploLight"; + position[] = {0,0,0}; + intensity = 0.005; + interval = 1; + lifeTime = 0.5; + }; + class GrenadeSmoke1 { + simulation = "particles"; + type = "ImpactSmoke2"; + position[] = {0,0,0}; + intensity = 0.15; + interval = 0.1; + lifeTime = 0.5; + }; +}; + diff --git a/addons/dragon/data/M47.rvmat b/addons/dragon/data/M47.rvmat new file mode 100644 index 0000000000..3241cd20d7 --- /dev/null +++ b/addons/dragon/data/M47.rvmat @@ -0,0 +1,81 @@ +class StageTI { + texture="z\ace\addons\dragon\data\m47_ti_ca.paa"; +}; +ambient[]={0.958,0.984,1,1}; +diffuse[]={0.958,0.984,1,1}; +forcedDiffuse[]={0,0,0,0}; +emmisive[]={0,0,0,1}; +specular[]={0.153,0.169,0.111,1}; +specularPower=90; +PixelShaderID="Super"; +VertexShaderID="Super"; +class Stage1 { + texture="z\ace\addons\dragon\data\m47_nohq.paa"; + uvSource="tex"; + class uvTransform { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,1}; + pos[]={0,0,0}; + }; +}; +class Stage2 { + texture="a3\weapons_f\Data\DetailMaps\Metal_rough_DT.paa"; + uvSource="tex"; + class uvTransform { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,1}; + pos[]={0,0,0}; + }; +}; +class Stage3 { + texture="#(argb,8,8,3)color(0,0,0,0,MC)"; + uvSource="tex"; + class uvTransform { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,1}; + pos[]={0,0,0}; + }; +}; +class Stage4 { + texture="z\ace\addons\dragon\data\m47_as.paa"; + uvSource="tex"; + class uvTransform { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,1}; + pos[]={0,0,0}; + }; +}; +class Stage5 { + texture="z\ace\addons\dragon\data\m47_smdi.paa"; + uvSource="tex"; + class uvTransform { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,1}; + pos[]={0,0,0}; + }; +}; +class Stage6 { + texture="#(ai,32,128,1)fresnel(4.01,2.86)"; + uvSource="tex"; + class uvTransform { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,1}; + pos[]={0,0,0}; + }; +}; +class Stage7 { + texture="a3\data_f\env_land_co.paa"; + uvSource="tex"; + class uvTransform { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,1}; + pos[]={0,0,0}; + }; +}; diff --git a/addons/dragon/data/M47mis.rvmat b/addons/dragon/data/M47mis.rvmat new file mode 100644 index 0000000000..b530ec030b --- /dev/null +++ b/addons/dragon/data/M47mis.rvmat @@ -0,0 +1,81 @@ +class StageTI { + texture="z\ace\addons\dragon\data\m47_ti_ca.paa"; +}; +ambient[]={0.989,1,0.958,1}; +diffuse[]={0.989,1,0.958,1}; +forcedDiffuse[]={0,0,0,0}; +emmisive[]={0,0,0,1}; +specular[]={0.159,0.212,0.196,1}; +specularPower=90; +PixelShaderID="Super"; +VertexShaderID="Super"; +class Stage1 { + texture="z\ace\addons\dragon\data\m47mis_nohq.paa"; + uvSource="tex"; + class uvTransform { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,1}; + pos[]={0,0,0}; + }; +}; +class Stage2 { + texture="a3\weapons_f\Data\DetailMaps\Metal_rough_DT.paa"; + uvSource="tex"; + class uvTransform { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,1}; + pos[]={0,0,0}; + }; +}; +class Stage3 { + texture="#(argb,8,8,3)color(0,0,0,0,MC)"; + uvSource="tex"; + class uvTransform { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,1}; + pos[]={0,0,0}; + }; +}; +class Stage4 { + texture="#(argb,8,8,3)color(1,1,1,1,AS)"; + uvSource="tex"; + class uvTransform { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,1}; + pos[]={0,0,0}; + }; +}; +class Stage5 { + texture="z\ace\addons\dragon\data\m47mis_smdi.paa"; + uvSource="tex"; + class uvTransform { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,1}; + pos[]={0,0,0}; + }; +}; +class Stage6 { + texture="#(ai,32,128,1)fresnel(4.01,2.86)"; + uvSource="tex"; + class uvTransform { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,1}; + pos[]={0,0,0}; + }; +}; +class Stage7 { + texture="a3\data_f\env_land_co.paa"; + uvSource="tex"; + class uvTransform { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,1}; + pos[]={0,0,0}; + }; +}; diff --git a/addons/dragon/data/dragon_text.paa b/addons/dragon/data/dragon_text.paa new file mode 100644 index 0000000000..a8a3787292 Binary files /dev/null and b/addons/dragon/data/dragon_text.paa differ diff --git a/addons/dragon/data/m47_as.paa b/addons/dragon/data/m47_as.paa new file mode 100644 index 0000000000..c561e39cf2 Binary files /dev/null and b/addons/dragon/data/m47_as.paa differ diff --git a/addons/dragon/data/m47_co.paa b/addons/dragon/data/m47_co.paa new file mode 100644 index 0000000000..5c621b5728 Binary files /dev/null and b/addons/dragon/data/m47_co.paa differ diff --git a/addons/dragon/data/m47_daysight_interaction_attach.paa b/addons/dragon/data/m47_daysight_interaction_attach.paa new file mode 100644 index 0000000000..0a9e19b461 Binary files /dev/null and b/addons/dragon/data/m47_daysight_interaction_attach.paa differ diff --git a/addons/dragon/data/m47_daysight_interaction_detach.paa b/addons/dragon/data/m47_daysight_interaction_detach.paa new file mode 100644 index 0000000000..7a0d5eb22e Binary files /dev/null and b/addons/dragon/data/m47_daysight_interaction_detach.paa differ diff --git a/addons/dragon/data/m47_daysight_item_ca.paa b/addons/dragon/data/m47_daysight_item_ca.paa new file mode 100644 index 0000000000..9768f42b9c Binary files /dev/null and b/addons/dragon/data/m47_daysight_item_ca.paa differ diff --git a/addons/dragon/data/m47_dragon_item_ca.paa b/addons/dragon/data/m47_dragon_item_ca.paa new file mode 100644 index 0000000000..0e87574794 Binary files /dev/null and b/addons/dragon/data/m47_dragon_item_ca.paa differ diff --git a/addons/dragon/data/m47_nohq.paa b/addons/dragon/data/m47_nohq.paa new file mode 100644 index 0000000000..e70a9f0ff2 Binary files /dev/null and b/addons/dragon/data/m47_nohq.paa differ diff --git a/addons/dragon/data/m47_smdi.paa b/addons/dragon/data/m47_smdi.paa new file mode 100644 index 0000000000..b6cd197ea8 Binary files /dev/null and b/addons/dragon/data/m47_smdi.paa differ diff --git a/addons/dragon/data/m47_ti_ca.paa b/addons/dragon/data/m47_ti_ca.paa new file mode 100644 index 0000000000..27c24a6599 Binary files /dev/null and b/addons/dragon/data/m47_ti_ca.paa differ diff --git a/addons/dragon/data/m47mis_co.paa b/addons/dragon/data/m47mis_co.paa new file mode 100644 index 0000000000..e76bee6f81 Binary files /dev/null and b/addons/dragon/data/m47mis_co.paa differ diff --git a/addons/dragon/data/m47mis_nohq.paa b/addons/dragon/data/m47mis_nohq.paa new file mode 100644 index 0000000000..6489813b6b Binary files /dev/null and b/addons/dragon/data/m47mis_nohq.paa differ diff --git a/addons/dragon/data/m47mis_smdi.paa b/addons/dragon/data/m47mis_smdi.paa new file mode 100644 index 0000000000..833a9c19c1 Binary files /dev/null and b/addons/dragon/data/m47mis_smdi.paa differ diff --git a/addons/dragon/functions/fnc_attackProfile_DRAGON.sqf b/addons/dragon/functions/fnc_attackProfile_DRAGON.sqf new file mode 100644 index 0000000000..b7adb597f5 --- /dev/null +++ b/addons/dragon/functions/fnc_attackProfile_DRAGON.sqf @@ -0,0 +1,77 @@ +#include "script_component.hpp" +/* + * Author: Brandon (TCVM) (Code inspired by NouberNou's Dragon Guidance) + * Attack profile: Dragon Guidance + * + * Arguments: + * 0: Seeker Target PosASL + * 1: Guidance Arg Array + * 2: Attack Profile State + * + * Return Value: + * Missile Aim PosASL - Unused + * + * Example: + * [[1,2,3], [], []] call ace_dragon_fnc_attackProfile_DRAGON; + * + * Public: No + */ +params ["_seekerTargetPos", "_args", "_attackProfileStateParams"]; +_args params ["_firedEH", "", "", "", "_stateParams"]; +_firedEH params ["_shooter","_weapon","","","","","_projectile"]; +_attackProfileStateParams params ["_maxCorrectableDistance", "_wireCut", "_seekerMaxRangeSqr", "_seekerMinRangeSqr", "_wireCutSource", "_lastTime", "_serviceInterval", "_serviceChargeCount", "_serviceChargeAcceleration", "_dragonSpeed"]; + +private _projectilePos = getPosASL _projectile; +private _distanceToProjectile = (getPosASL _shooter) vectorDistanceSqr _projectilePos; +private _retPos = _projectilePos vectorAdd (AGLtoASL (_projectile vectorModelToWorld [0, 50, 0])); + +// _shooter returns the vehicle that shot it. If the launcher dies, the wire would probably be cut so assume it +if ((_distanceToProjectile > _seekerMaxRangeSqr) || _wireCut || { !alive _shooter }) exitWith { + // wire snap, random direction + if (!_wireCut) then { + _attackProfileStateParams set [1, true]; + playSound3D ["a3\sounds_f\air\sfx\SL_rope_break.wss", objNull, false, AGLtoASL (_shooter modelToWorld _wireCutSource), 5, 1, 25]; + }; + + if (_serviceChargeCount > 0 && {(_lastTime - CBA_missionTime) <= 0}) then { + _attackProfileStateParams set [5, CBA_missionTime + 0.05 + random 0.1]; + private _randomVector = [(random 2) - 1, random 1, (random 2) - 1]; + _projectile setVelocityModelSpace ((velocityModelSpace _projectile) vectorAdd (_randomVector vectorMultiply _serviceChargeAcceleration)); + private _charge = createVehicle [QGVAR(serviceCharge), [0, 0, 0], [], 0, "NONE"]; + _charge setPosASL (_projectilePos vectorAdd ((_randomVector vectorMultiply -1) vectorMultiply 0.025)); + _attackProfileStateParams set [7, _serviceChargeCount - 1]; + }; + + _retPos +}; + +if (_distanceToProjectile <= _seekerMinRangeSqr || { _serviceChargeCount <= 0 } || { !(_shooter getVariable [QGVAR(sightAttached), true]) }) exitWith { _retPos }; + +// if the time between updates is less than the pop time we want to fire the rockets OR if the missile wants to make a major correction pop it rapidly +if (((_lastTime - CBA_missionTime) <= 0) || {(_lastTime - CBA_missionTime) < (_serviceInterval / 2) && (_projectilePos vectorDistance _seekerTargetPos > 1)}) then { + _attackProfileStateParams set [5, CBA_missionTime + _serviceInterval]; + + private _vectorToCrosshair = vectorNormalized (_projectile worldToModel (ASLToAGL _seekerTargetPos)); + private _vectorToPos = vectorNormalized (((_projectile vectorWorldToModelVisual (_shooter weaponDirection _weapon)) vectorMultiply (_dragonSpeed * _serviceInterval)) vectorAdd (_vectorToCrosshair vectorMultiply _maxCorrectableDistance)); + + if ((_vectorToPos select 2) < 0) then { + _vectorToPos set [2, 0]; + } else { + private _a = _vectorToPos select 1; + private _b = _vectorToPos select 2; + // The booster has some angle to it, so we introduce that axis if the angle is too low + if (abs(_a) > 0 && { abs(atan (_b / _a)) < DRAGON_BOOSTER_ANGLE }) then { + _vectorToPos set [2, abs(_a)]; + }; + }; + + _projectile setVelocityModelSpace ((velocityModelSpace _projectile) vectorAdd (_vectorToPos vectorMultiply _serviceChargeAcceleration)); + + private _charge = createVehicle [QGVAR(serviceCharge), [0, 0, 0], [], 0, "NONE"]; + _charge setPosASL (_projectilePos vectorAdd ((_vectorToCrosshair vectorMultiply -1) vectorMultiply 0.025)); + + _attackProfileStateParams set [7, _serviceChargeCount - 1]; +}; + +_retPos + diff --git a/addons/dragon/functions/fnc_canPickupTripod.sqf b/addons/dragon/functions/fnc_canPickupTripod.sqf new file mode 100644 index 0000000000..c328c66bd6 --- /dev/null +++ b/addons/dragon/functions/fnc_canPickupTripod.sqf @@ -0,0 +1,25 @@ +#include "script_component.hpp" +/* + * Author: Brandon (TCVM) + * Determines if you can pick-up the Dragon missile. If the missile was fired you will not be able to pick up the tripod. + * + * Arguments: + * 0: Target + * 1: Unit Performing Action + * + * Return Value: + * Can Pickup Tripod + * + * Example: + * [vehicle player, player] call ace_dragon_fnc_canPickupTripod; + * + * Public: No + */ +params ["_target", "_unit"]; + +(alive _target) +&& {!alive (gunner _target)} +&& {!(_target getVariable [QGVAR(fired), false])} +&& {!(_target getVariable [QGVAR(sightAttached), ((typeOf _target) == QGVAR(staticAssembled))])} +&& EFUNC(csw,assemble_canPickupTripod) + diff --git a/addons/dragon/functions/fnc_onFired.sqf b/addons/dragon/functions/fnc_onFired.sqf new file mode 100644 index 0000000000..78d9d15b91 --- /dev/null +++ b/addons/dragon/functions/fnc_onFired.sqf @@ -0,0 +1,53 @@ +#include "script_component.hpp" +/* + * Author: Brandon (TCVM) + * Runs when Dragon is fired + * + * Arguments: + * 0: None + * 1: The weapon that was fired + * + * Return Value: + * None + * + * Example: + * [any, vehicle player] call ace_dragon_fnc_onFired; + * + * Public: No + */ +params ["_firedEH", "", "", "_seekerParams", "_stateParams"]; +_firedEH params ["_shooter","_weapon","","","","","_projectile"]; +_stateParams params ["", "", "_attackProfileStateParams"]; +_seekerParams params ["", "", "_seekerMaxRange", "_seekerMinRange"]; + +_shooter setVariable [QGVAR(fired), true, true]; +_shooter animate ["missile_hide", 1]; + +private _config = ([_projectile] call CBA_fnc_getObjectConfig) >> "ace_missileguidance"; + +private _serviceInterval = [_config >> "serviceInterval", "NUMBER", 0.33] call CBA_fnc_getConfigEntry; +private _serviceChargeCount = [_config >> "serviceCharges", "NUMBER", 60] call CBA_fnc_getConfigEntry; +private _serviceChargeAcceleration = [_config >> "serviceChargeAcceleration", "NUMBER", 6.5] call CBA_fnc_getConfigEntry; +private _dragonSpeed = [_config >> "dragonSpeed", "NUMBER", 100] call CBA_fnc_getConfigEntry; +private _maxCorrectableDistance = [_config >> "correctionDistance", "NUMBER", DEFAULT_CORRECTION_DISTANCE] call CBA_fnc_getConfigEntry; +private _maxDistanceSqr = _seekerMaxRange * _seekerMaxRange; +private _minDistanceSqr = _seekerMinRange * _seekerMinRange; + +private _turretPath = [_shooter, _weapon] call CBA_fnc_turretPathWeapon; +private _turretConfig = [_shooter, _turretPath] call CBA_fnc_getTurret; + +private _wireCutSource = _shooter selectionPosition getText(_turretConfig >> "missileEnd"); + +_attackProfileStateParams append [ + _maxCorrectableDistance, + false, + _maxDistanceSqr, + _minDistanceSqr, + _wireCutSource, + CBA_missionTime, + _serviceInterval, + _serviceChargeCount, + _serviceChargeAcceleration, + _dragonSpeed +]; + diff --git a/addons/dragon/functions/fnc_sightAttach.sqf b/addons/dragon/functions/fnc_sightAttach.sqf new file mode 100644 index 0000000000..6ad5df2077 --- /dev/null +++ b/addons/dragon/functions/fnc_sightAttach.sqf @@ -0,0 +1,33 @@ +#include "script_component.hpp" +/* + * Author: Brandon (TCVM) + * Attaches the sighting unit to the Dragon missile. + * + * Arguments: + * 0: Target + * 1: Unit Performing Action + * 2: Is event (function recursives globaly to set weapon where turret is local) (default: false) + * + * Return Value: + * Can Attach Sighting Unit + * + * Example: + * [cursorObject, player] call ace_dragon_fnc_sightAttach + * + * Public: No + */ + +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 {}; + _target setVariable [QGVAR(sightAttached), true, true]; + _target animate ["optic_hide", 0]; + _target addWeapon QGVAR(superStatic); + _target removeWeapon QGVAR(dummyStatic); + TRACE_2("added sight",_target weaponsTurret [0],_target animationPhase "optic_hide"); +} else { + _unit removeWeapon QGVAR(sight); + [QGVAR(attachSight), [_target, _unit, true]] call CBA_fnc_globalEvent; +}; diff --git a/addons/dragon/functions/fnc_sightCanAttach.sqf b/addons/dragon/functions/fnc_sightCanAttach.sqf new file mode 100644 index 0000000000..9ec742d19b --- /dev/null +++ b/addons/dragon/functions/fnc_sightCanAttach.sqf @@ -0,0 +1,23 @@ +#include "script_component.hpp" +/* + * Author: Brandon (TCVM) + * Determines if you can attach the sighting unit to the Dragon missile. + * + * Arguments: + * 0: Target + * 1: Unit Performing Action + * + * Return Value: + * Can Attach Sighting Unit + * + * Example: + * [cursorObject, player] call ace_dragon_fnc_sightCanAttach + * + * Public: No + */ + +params ["_target", "_unit"]; + +(alive _target) +&& {!(_target getVariable [QGVAR(sightAttached), ((typeOf _target) == QGVAR(staticAssembled))])} +&& {QGVAR(sight) in (weapons _unit)} diff --git a/addons/dragon/functions/fnc_sightCanDetach.sqf b/addons/dragon/functions/fnc_sightCanDetach.sqf new file mode 100644 index 0000000000..92c4a9a913 --- /dev/null +++ b/addons/dragon/functions/fnc_sightCanDetach.sqf @@ -0,0 +1,22 @@ +#include "script_component.hpp" +/* + * Author: Brandon (TCVM) + * Determines if you can attach the sighting unit to the Dragon missile. + * + * Arguments: + * 0: Target + * 1: Unit Performing Action + * + * Return Value: + * Can Attach Sighting Unit + * + * Example: + * [cursorObject, player] call ace_dragon_fnc_sightCanDetach + * + * Public: No + */ + +params ["_target", "_unit"]; + +(alive _target) +&& {_target getVariable [QGVAR(sightAttached), ((typeOf _target) == QGVAR(staticAssembled))]} diff --git a/addons/dragon/functions/fnc_sightDetach.sqf b/addons/dragon/functions/fnc_sightDetach.sqf new file mode 100644 index 0000000000..161a13ba64 --- /dev/null +++ b/addons/dragon/functions/fnc_sightDetach.sqf @@ -0,0 +1,39 @@ +#include "script_component.hpp" +/* + * Author: Brandon (TCVM) + * Attaches the sighting unit to the Dragon missile. + * + * Arguments: + * 0: Target + * 1: Unit Performing Action + * 2: Is event (function recursives globaly to set weapon where turret is local) (default: false) + * + * Return Value: + * Can Attach Sighting Unit + * + * Example: + * [cursorObject, player] call ace_dragon_fnc_sightDetach; + * + * Public: No + */ + +params ["_target", "_unit"]; + +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 {}; + _target setVariable [QGVAR(sightAttached), false, true]; + _target animate ["optic_hide", 1]; + _target removeWeapon QGVAR(superStatic); + _target addWeapon QGVAR(dummyStatic); + TRACE_2("removed sight",_target weaponsTurret [0],_target animationPhase "optic_hide"); +} else { + if ((binocular _unit) == "") then { + _unit addWeapon QGVAR(sight); + } else { + [_unit, QGVAR(sight)] call EFUNC(common,addToInventory); + }; + [QGVAR(detachSight), [_target, _unit, true]] call CBA_fnc_globalEvent; +}; diff --git a/addons/dragon/functions/script_component.hpp b/addons/dragon/functions/script_component.hpp new file mode 100644 index 0000000000..386679ecf6 --- /dev/null +++ b/addons/dragon/functions/script_component.hpp @@ -0,0 +1 @@ +#include "\z\ace\addons\dragon\script_component.hpp" \ No newline at end of file diff --git a/addons/dragon/models/ace_m47_magazine.p3d b/addons/dragon/models/ace_m47_magazine.p3d new file mode 100644 index 0000000000..ac09112e91 Binary files /dev/null and b/addons/dragon/models/ace_m47_magazine.p3d differ diff --git a/addons/dragon/models/ace_m47_optic.p3d b/addons/dragon/models/ace_m47_optic.p3d new file mode 100644 index 0000000000..355c6b04b5 Binary files /dev/null and b/addons/dragon/models/ace_m47_optic.p3d differ diff --git a/addons/dragon/models/ace_m47_static.p3d b/addons/dragon/models/ace_m47_static.p3d new file mode 100644 index 0000000000..3c3a6b0731 Binary files /dev/null and b/addons/dragon/models/ace_m47_static.p3d differ diff --git a/addons/dragon/models/dragon.p3d b/addons/dragon/models/dragon.p3d new file mode 100644 index 0000000000..4416a2d7a9 Binary files /dev/null and b/addons/dragon/models/dragon.p3d differ diff --git a/addons/dragon/models/model.cfg b/addons/dragon/models/model.cfg new file mode 100644 index 0000000000..ab93f7e9a8 --- /dev/null +++ b/addons/dragon/models/model.cfg @@ -0,0 +1,94 @@ +class CfgSkeletons { + class Default { + isDiscrete = 1; + skeletonInherit = ""; + skeletonBones[] = {}; + }; + + class ace_m47_static_skeleton: Default { + skeletonInherit = "Default"; + skeletonBones[] = { + "bipod","", + "grav_box","bipod", + "launcher","grav_box", + "optic","launcher", + "missile","launcher" + }; + }; +}; + +class CfgModels { + class Default { + sectionsInherit = ""; + sections[] = {}; + }; + + class ace_m47_static: Default { + sectionsInherit = "Default"; + sections[] = {}; + skeletonName = "ace_m47_static_skeleton"; + class Animations { + class MainGun { + type="rotation"; + selection="launcher"; + sourceAddress = "clamp"; + source="MainGun"; + axis="elevate_axis"; + animPeriod=0.01; + initPhase=0; + maxValue="rad 360"; + minValue="rad -360"; + angle1="rad 360"; + angle0="rad -360"; + }; + class MainTurret { + type="rotation"; + source="MainTurret"; + selection="bipod"; + sourceAddress = "loop"; + axis="rotate_axis"; + animPeriod=0.005; + minValue="rad -360"; + maxValue="rad +360"; + angle0="rad -360"; + angle1="rad +360"; + }; + class rest_rotate { + type="rotation"; + selection="grav_box"; + sourceAddress = "clamp"; + source="user"; + axis="elevate_axis"; + animPeriod=0.00001; + initPhase=-0.35; + maxValue="3.60"; + minValue="-3.60"; + angle1="rad -360"; + angle0="rad 360"; + }; + class optic_hide { + type = "hide"; + source = "user"; + selection = "optic"; + animPeriod = 0.0001; + minValue = 0; + maxValue = 1; + minPhase = 0; + maxPhase = 1; + hideValue = 0.99; + initPhase = 1; + }; + class missile_hide { + type = "hide"; + source = "user"; + selection = "missile"; + animPeriod = 0.0001; + minValue = 0; + maxValue = 1; + minPhase = 0; + maxPhase = 1; + hideValue = 0.99; + }; + }; + }; +}; diff --git a/addons/dragon/models/optics_m47.p3d b/addons/dragon/models/optics_m47.p3d new file mode 100644 index 0000000000..08183a1f0e Binary files /dev/null and b/addons/dragon/models/optics_m47.p3d differ diff --git a/addons/dragon/script_component.hpp b/addons/dragon/script_component.hpp new file mode 100644 index 0000000000..77521b2c6a --- /dev/null +++ b/addons/dragon/script_component.hpp @@ -0,0 +1,18 @@ +#define COMPONENT dragon +#define COMPONENT_BEAUTIFIED M47 Dragon +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_DRAGON + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_DRAGON + #define DEBUG_SETTINGS DEBUG_SETTINGS_DRAGON +#endif + +#include "\z\ace\addons\main\script_macros.hpp" +#define DRAGON_BOOSTER_ANGLE 45 diff --git a/addons/dragon/sounds/M47_1.wss b/addons/dragon/sounds/M47_1.wss new file mode 100644 index 0000000000..4b1949aa49 Binary files /dev/null and b/addons/dragon/sounds/M47_1.wss differ diff --git a/addons/dragon/sounds/M47_2.wss b/addons/dragon/sounds/M47_2.wss new file mode 100644 index 0000000000..c630402c5b Binary files /dev/null and b/addons/dragon/sounds/M47_2.wss differ diff --git a/addons/dragon/sounds/dry.wss b/addons/dragon/sounds/dry.wss new file mode 100644 index 0000000000..e54a8ab4e9 Binary files /dev/null and b/addons/dragon/sounds/dry.wss differ diff --git a/addons/dragon/sounds/rocket_fly.wss b/addons/dragon/sounds/rocket_fly.wss new file mode 100644 index 0000000000..76264b1246 Binary files /dev/null and b/addons/dragon/sounds/rocket_fly.wss differ diff --git a/addons/dragon/sounds/rocket_reload.wss b/addons/dragon/sounds/rocket_reload.wss new file mode 100644 index 0000000000..8cdce5a7f8 Binary files /dev/null and b/addons/dragon/sounds/rocket_reload.wss differ diff --git a/addons/dragon/sounds/service_charge.wss b/addons/dragon/sounds/service_charge.wss new file mode 100644 index 0000000000..1cafccaa91 Binary files /dev/null and b/addons/dragon/sounds/service_charge.wss differ diff --git a/addons/dragon/stringtable.xml b/addons/dragon/stringtable.xml new file mode 100644 index 0000000000..f78c1f9684 --- /dev/null +++ b/addons/dragon/stringtable.xml @@ -0,0 +1,33 @@ + + + + + [CSW] M47 Super-Dragon + [CSW] M47 Super-Dragon + + + M47 Super-Dragon + M47 Super-Dragon + + + Attach Sight + Colocar Mira + + + Detach Sight + Remover Mira + + + SU-36/P Daysight + SU-36/P Daysight + + + A light, cheap sight used for daytime operations. Contains the guidance computer for the whole system + Uma mira leve e comum utilizada para operações de dia. Contêm o computador de orientação para todo o sistema. + + + A Wire-Guided SACLOS missile with a unique flight characteristic + Um míssil SACLOS, guiado por fio com uma característica única de vôo + + + diff --git a/addons/explosives/Cfg3DEN.hpp b/addons/explosives/Cfg3DEN.hpp new file mode 100644 index 0000000000..d36baa9c40 --- /dev/null +++ b/addons/explosives/Cfg3DEN.hpp @@ -0,0 +1,22 @@ +#define DEFAULT_IS_EOD (_this getUnitTrait 'explosiveSpecialist') + +class Cfg3DEN { + class Object { + class AttributeCategories { + class ace_attributes { + class Attributes { + class ace_isEOD { + displayName = CSTRING(IsEOD_DisplayName); + tooltip = CSTRING(IsEOD_Description); + property = QUOTE(ace_isEOD); + control = "Checkbox"; + expression = QUOTE(_this setVariable [ARR_3('ACE_isEOD',_value,true)]); + defaultValue = QUOTE(DEFAULT_IS_EOD); + condition = "objectBrain"; + typeName = "BOOL"; + }; + }; + }; + }; + }; +}; diff --git a/addons/explosives/CfgAmmo.hpp b/addons/explosives/CfgAmmo.hpp index 722fbf213c..c02885362e 100644 --- a/addons/explosives/CfgAmmo.hpp +++ b/addons/explosives/CfgAmmo.hpp @@ -164,7 +164,7 @@ class CfgAmmo { class ACE_IEDLandSmall_Command_Ammo: IEDLandSmall_Remote_Ammo { mineTrigger = "RemoteTrigger"; }; - class ACE_IEDLandSmall_Range_Ammo: IEDLandBig_Remote_Ammo { + class ACE_IEDLandSmall_Range_Ammo: IEDLandSmall_Remote_Ammo { mineTrigger = "RangeTriggerShort"; }; diff --git a/addons/explosives/config.cpp b/addons/explosives/config.cpp index 3d2077ff1d..0ae218be25 100644 --- a/addons/explosives/config.cpp +++ b/addons/explosives/config.cpp @@ -16,6 +16,7 @@ class CfgPatches { #include "ACE_Settings.hpp" #include "CfgEventHandlers.hpp" +#include "Cfg3DEN.hpp" #include "CfgAmmo.hpp" #include "CfgMagazines.hpp" #include "CfgWeapons.hpp" diff --git a/addons/explosives/stringtable.xml b/addons/explosives/stringtable.xml index 8923f1c5dd..2240642084 100644 --- a/addons/explosives/stringtable.xml +++ b/addons/explosives/stringtable.xml @@ -882,7 +882,7 @@ Mina M6 SLAM (atak od boku) Mina M6 SLAM (Ataque Lateral) Mine M6 SLAM (de flanc) - STR_ACE_Explosives_Module_SLAMBottomAttack_DisplayName M6 SLAM Mine (Bottom Attack) Mine M6 SLAM (par le bas) M6-SLAM-Mine (Bodenangriff) Mina M6 SLAM (base) Mina M6 SLAM (atak od dołu) Mina M6 SLAM (Laterale) + Mina M6 SLAM (Laterale) M6 SLAM (Útok do strany) Mina M6 SLAM (Ataque Lateral) Мина M6 SLAM (направлена вбок) @@ -1006,10 +1006,11 @@ Cavo d'innesco 绊线闪光地雷 絆線閃光地雷 + Tripwire (Sinalizador) 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 @@ -1018,21 +1019,36 @@ Tipo: Cavo d'innesco - Sfocio un abbaglio non letale quanto attivato. <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 Explosive range + Explosionsradius Portée du détonateur 爆発範囲 爆炸范围 爆炸範圍 Raggio di detonazione Zasięg wybuchu + Дальность подрыва + Alcance do explosivo Explosive Timer + Detonationszeit Timer di detonazione 爆発タイマー Czasomierz Wybuchu + Таймер взрывчатки + Timer de explosão + + + Is EOD + Kampfmittelbeseitigung + + + Controls whether the unit is an explosive specialist. + Steuert, ob die Einheit ein Sprengstoffspezialist ist. diff --git a/addons/fastroping/stringtable.xml b/addons/fastroping/stringtable.xml index 71a2f17038..ac506c335e 100644 --- a/addons/fastroping/stringtable.xml +++ b/addons/fastroping/stringtable.xml @@ -55,6 +55,8 @@ 收起快速绳降系统 패스트 로프 시스템 보관 Schowaj system zjazdu na linach + Спрятать систему спуска + Recolher o sistema de descida rápida Deploy ropes @@ -146,81 +148,120 @@ Deploy 12m ropes + 12m Seile einsetzen Déployer les cordes 12m 12m ロープを展開 Wysuń linę o długości 12 m. + Выпустить 12 м канат + Jogar cordar (12m) Deploy 15m ropes + 15m Seile einsetzen Déployer les cordes 15m 15m ロープを展開 Wysuń linę o długości 15 m. + Выпустить 15 м канат + Jogar cordar (15m) Deploy 18m ropes + 18m Seile einsetzen Déployer les cordes 18m 18m ロープを展開 Wysuń linę o długości 18 m. + Выпустить 18 м канат + Jogar cordar (18m) Deploy 27m ropes + 27m Seile einsetzen Déployer les cordes 27m 27m ロープを展開 Wysuń linę o długości 27 m. + Выпустить 27 м канат + Jogar cordar (27m) Deploy 36m ropes + 36m Seile einsetzen Déployer les cordes 36m 36m ロープを展開 Wysuń linę o długości 36 m. + Выпустить 36 м канат + Jogar cordar (36m) [ACE] Ropes Supply crate + [ACE] Seil Versorgungskiste [ACE] Caisse de Cordes [ACE] ロープ収納箱 Skrzynia z linami ACE + [ACE] Ящик с канатами + [ACE] Suprimento de cordas Used to do deploy ropes from a compatibile helicopter + Wird zum Bereitstellen von Seilen aus einem kompatiblen Hubschrauber verwendet Utilisé pour déployer des cordes depuis un hélicoptère compatible 対応するヘリコプターからロープを展開する為に使用されます Używane do opuszczania lin z kompatybilnych smigłowców + Используется для выпуска канатов с совместимого вертолета + Usado para fazer descida rápida de corda em helicópteros compatíveis com FRIES Rope 12.2 meters + 12.2 Meter Seil Corde 12.2 mètres ロープ (12.2 メートル) Lina, długość 12,2 m. + Канат 12.2 метров + Corda (12.2m) Rope 15.2 meters + 15.2 Meter Seil Corde 15.2 mètres ロープ (15.2 メートル) Lina, długość 15,2 m. + Канат 15.2 метров + Corda (15.2m) Rope 18.3 meters + 18.3 Meter Seil Corde 18.3 mètres ロープ (18.3 メートル) Lina, długość 18,3 m. + Канат 18.3 метров + Corda (18.3m) Rope 27.4 meters + 27.4 Meter Seil Corde 27.4 mètres ロープ (27.4 メートル) Lina, długość 27,4 m. + Канат 27.4 метров + Corda (27.4m) Rope 36.6 meters + 36.6 Meter Seil Corde 36.6 mètres ロープ (36.6 メートル) Lina, długość 36,6 m. + Канат 36.6 метров + Corda (36.6m) Require rope item to deploy + Seil-Item zum aufbauen benötigt Exiger une corde pour déployer 展開にはロープ アイテムを必須に Wymaga przedmiotu typu lina + Требуется канат + Requer uma corda para jogar diff --git a/addons/fcs/config.cpp b/addons/fcs/config.cpp index df849ec346..88e803d0ca 100644 --- a/addons/fcs/config.cpp +++ b/addons/fcs/config.cpp @@ -28,7 +28,10 @@ class CfgPatches { #include "CfgOptics.hpp" class ACE_Extensions { - extensions[] += {"ace_fcs"}; + class ace_fcs { + windows = 1; + client = 1; + }; }; class ACE_Tests { diff --git a/addons/finger/stringtable.xml b/addons/finger/stringtable.xml index 24941404c5..5722ba52b0 100644 --- a/addons/finger/stringtable.xml +++ b/addons/finger/stringtable.xml @@ -11,6 +11,8 @@ 가리키기 Pointage Wskazywanie + Указание пальцем + Apontando Show pointing indicator to self diff --git a/addons/flashlights/stringtable.xml b/addons/flashlights/stringtable.xml index 418c10cc6a..bd87c4e847 100644 --- a/addons/flashlights/stringtable.xml +++ b/addons/flashlights/stringtable.xml @@ -93,12 +93,15 @@ Map light color + Farbe des Kartenlichts Couleur de la lampe sur carte 光の色 地图上手电的颜色 地圖上使用手電筒的顏色 Colore della luce sulla mappa Kolor światła na mapie + Цвет подсветки карты + Cor da lanterna no mapa diff --git a/addons/gforces/stringtable.xml b/addons/gforces/stringtable.xml index 737188f76b..89ffa42375 100644 --- a/addons/gforces/stringtable.xml +++ b/addons/gforces/stringtable.xml @@ -6,7 +6,7 @@ Effekte der G-Kräfte Efectos Gforces G Force efekty - Efeitos de ForçaG + Efeitos da Força G Effets de force gravitationnelle Эффекты перегрузок G による効果 @@ -33,12 +33,15 @@ G-force reduction + G-Kräfte Reduzierung Reduction des Gs 耐 G 性 减少G力 減少G力 Riduzione forza G Redukcja przeciążenia + Уменьшение перегрузок + Redução de Força-G diff --git a/addons/goggles/stringtable.xml b/addons/goggles/stringtable.xml index a4be10b0fc..d35943c305 100644 --- a/addons/goggles/stringtable.xml +++ b/addons/goggles/stringtable.xml @@ -10,6 +10,8 @@ ゴーグル 고글 Gogle + Очки + Óculos Show Goggle Effects in Third Person @@ -54,6 +56,7 @@ Effetti Occhiali 护目镜效果 護目鏡效果 + Efeitos de Óculos Tint @@ -66,6 +69,7 @@ Colore 染色 染色 + Cor Tint + Effects @@ -78,6 +82,7 @@ Colore + Effetti 染色 + 影响 染色 + 影響 + Cor + Efeitos diff --git a/addons/grenades/CfgMagazineWells.hpp b/addons/grenades/CfgMagazineWells.hpp index 0ce8abca35..7ac4a555dd 100644 --- a/addons/grenades/CfgMagazineWells.hpp +++ b/addons/grenades/CfgMagazineWells.hpp @@ -2,4 +2,7 @@ class CfgMagazineWells { class CBA_40mm_M203 { ADDON[] = {"ACE_40mm_flare_white", "ACE_40mm_flare_red", "ACE_40mm_flare_green", "ACE_40mm_flare_ir"}; }; + class UGL_40x36 { + ADDON[] = {"ACE_40mm_flare_white", "ACE_40mm_flare_red", "ACE_40mm_flare_green", "ACE_40mm_flare_ir"}; + }; }; diff --git a/addons/grenades/functions/fnc_flashbangExplosionEH.sqf b/addons/grenades/functions/fnc_flashbangExplosionEH.sqf index b70314d2d0..7beb128df6 100644 --- a/addons/grenades/functions/fnc_flashbangExplosionEH.sqf +++ b/addons/grenades/functions/fnc_flashbangExplosionEH.sqf @@ -27,6 +27,7 @@ if (hasInterface) then { _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 [{ @@ -73,6 +74,9 @@ _affected = _affected - [ACE_player]; // Affect local player, independently of distance if (hasInterface && {!isNull ACE_player} && {alive ACE_player}) then { + if ((getNumber (configFile >> "CfgVehicles" >> (typeOf 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 diff --git a/addons/grenades/functions/fnc_throwGrenade.sqf b/addons/grenades/functions/fnc_throwGrenade.sqf index 0fe0c483d9..1c8066dec2 100644 --- a/addons/grenades/functions/fnc_throwGrenade.sqf +++ b/addons/grenades/functions/fnc_throwGrenade.sqf @@ -37,9 +37,31 @@ if (local _unit) then { }; if (getNumber (_config >> QGVAR(flashbang)) == 1) then { - private _fuzeTime = getNumber (_config >> "explosionTime"); + private _bangs = 1; + private _entry = _config >> QGVAR(flashbangBangs); + if (isNumber _entry || isText _entry) then { + _bangs = getNumber _entry; + }; - [FUNC(flashbangThrownFuze), [_projectile], _fuzeTime] call CBA_fnc_waitAndExecute; + 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; + }; + + for "_i" from 0 to (_bangs - 1) do { + private _fuzeTime = _fuzeTimeBase + _i*_interval + random [- _maxDeviation, 0, _maxDeviation]; + + [FUNC(flashbangThrownFuze), [_projectile], _fuzeTime] call CBA_fnc_waitAndExecute; + }; }; }; diff --git a/addons/grenades/stringtable.xml b/addons/grenades/stringtable.xml index 3483b74037..c0fc97b833 100644 --- a/addons/grenades/stringtable.xml +++ b/addons/grenades/stringtable.xml @@ -136,7 +136,7 @@ Aussi connu en tant que "Flashbang". Explose en causant cécité, surdité, bourdonnements d'oreilles et perturbation de l'oreille interne. Znany też jako flashbang. Powoduje natychmiastową tymczasową ślepotę, głuchotę, dzwonienie w uszach i inne zaburzenia ucha wewnętrznego. Omračující granát je taktická nesmrtící zbraň používaná při záchraně rukojmí a zvládání davu. - XM84 (M84) - граната нелетального действия, и предназначена для отвлечения и временного вывода из строя, либо дезориентации противника. Основное использование нашла при освобождении заложников, захвате преступников и террористов, а также проведении диверсионных миссий. + XM84 (M84) - граната нелетального действия, предназначена для отвлечения и временного вывода из строя, либо дезориентации противника. Основное использование нашла при освобождении заложников, захвате преступников и террористов, а также проведении диверсионных миссий. Villanógránát néven is ismert. Azonnali villanási vakságot, süketséget, fülzúgást, és belső füli zavart okoz. 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. @@ -201,7 +201,7 @@ M127A1 Bengala (Giallo) Flara ręczna sygnałowa M127A1 (żółta) M127A1 Sinalizador (Amarelo) - M127A1 Фальшфейер (Жёлтые) + M127A1 Фальшфейер (Жёлтый) Bengala M127A1 (Amarilla) M127A1 Feux à main (Jaune) M127A1 信号弾 (黄) @@ -265,7 +265,7 @@ Bengala (Giallo) Flara ręczna (żółta) Sinalizador de Mão (Amarelo) - Фальшфейер (Жёлтые) + Фальшфейер (Жёлтый) Bengala (Amarilla) Feux à main (Jaune) 黄の手持ち式信号弾 @@ -330,7 +330,7 @@ M127A1 (Giallo) M127A1 (żółta) M127A1 (Amarelo) - M127A1 (Жёлтые) + M127A1 (Жёлтый) M127A1 (Amarilla) M127A1 (黄) M127A1 (노랑) @@ -348,6 +348,7 @@ AN-M14 Granata Incendiaria AN-M14 燃烧手榴弹 AN-M14 燃燒手榴彈 + Granada Incendiária AN-M14 AN-M14 @@ -360,6 +361,7 @@ AN-M14 AN-M14 AN-M14 + AN-M14 Incendiary grenade used to destroy weapons, ammunition and other equipment. @@ -372,42 +374,55 @@ Granata incendiaria usata per distruggere armi, munizioni e altri equipaggiamenti. 燃烧手榴弹是用来摧毁武器,弹药以及其他装备的好帮手。 燃燒手榴彈是用來摧毀武器,彈藥以及其他裝備的好幫手 + Granada Incendiária utilizada para destruir armas, munições e outros equipamentos. Type: Star Parachute Flare Typ: Gwiezdna Flara Spadochronowa Tipo: Granata a paracadute con bengala 種類: パラシュート式照明弾 (星弾) + Тип: Осветительная ракета - звезда на парашюте + Tipo: Sinalizador de pára-quedas estrela M583 Illumination Flare (White) M583 Flara oświetlająca (Biała) M583 Granata con bengala (Bianca) M583 照明弾 (白) + M583 Осветит. ракета (Белая) + M583 Sinalizador de Iluminação (Branco) M662 Illumination Flare (Red) M662 Flara oświetlająca (Czerwona) M662 Granata con bengala (Rossa) M662 照明弾 (赤) + M662 Осветит. ракета (Красная) + M662 Sinalizador de Iluminação (Vermelho) M661 Illumination Flare (Green) M661 Flara oświetlająca (Zielona) M661 Granata con bengala (Verde) M661 照明弾 (緑) + M661 Осветит. ракета (Зеленая) + M661 Sinalizador de Iluminação (Verde) Type: Parachute IR Flare Typ: Spadochronowa Flara IR Tipo: Granata a paracadute con infrarosso 種類: パラシュート式赤外線照明弾 + Тип: ИК-осветительная ракета на парашюте + Tipo: Sinalizador Infravermelho de Pára-quedas M992 Illumination IR Flare M992 Oświetlająca flara IR M992 Granata con infrarosso M992 赤外線照明弾 + M992 ИК-осветительная ракета + M992 Sinalizador de Iluminação Infravermelho diff --git a/addons/gunbag/CfgVehicles.hpp b/addons/gunbag/CfgVehicles.hpp index e23966cfa2..0addf22710 100644 --- a/addons/gunbag/CfgVehicles.hpp +++ b/addons/gunbag/CfgVehicles.hpp @@ -73,6 +73,7 @@ class CfgVehicles { hiddenSelectionsTextures[] = {QPATHTOF(data\gunbag_co.paa)}; maximumLoad = 80; mass = 11; + ADDON = 1; }; class GVAR(Tan): ADDON { diff --git a/addons/gunbag/functions/fnc_calculateMass.sqf b/addons/gunbag/functions/fnc_calculateMass.sqf index 8f845dc4ee..6d66d191df 100644 --- a/addons/gunbag/functions/fnc_calculateMass.sqf +++ b/addons/gunbag/functions/fnc_calculateMass.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" /* * Author: Ir0n1E - * Calculate mass of weapon an items. + * Calculate mass of weapon and items. * * Arguments: * 0: Weapon diff --git a/addons/gunbag/functions/fnc_canInteract.sqf b/addons/gunbag/functions/fnc_canInteract.sqf index 46451b50d5..fbf17819f6 100644 --- a/addons/gunbag/functions/fnc_canInteract.sqf +++ b/addons/gunbag/functions/fnc_canInteract.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" /* * Author: Ir0n1E - * Check if client able to interact with gunbag. + * Check if client is able to interact with gunbag. * * Arguments: * 0: Unit diff --git a/addons/gunbag/functions/fnc_hasGunbag.sqf b/addons/gunbag/functions/fnc_hasGunbag.sqf index 5fa90c7b9c..7f9c7135e0 100644 --- a/addons/gunbag/functions/fnc_hasGunbag.sqf +++ b/addons/gunbag/functions/fnc_hasGunbag.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" /* * Author: Ir0n1E - * Switches gunbag full/empty for mass calculation. + * Check if unit has a gunbag. * * Arguments: * 0: Unit @@ -17,4 +17,4 @@ params ["_unit"]; -(backpackContainer _unit) isKindOf QUOTE(ADDON) +getNumber (configFile >> "CfgVehicles" >> (backpack _unit) >> QUOTE(ADDON)) == 1 diff --git a/addons/gunbag/stringtable.xml b/addons/gunbag/stringtable.xml index ab4fdf5ac7..c83352474a 100644 --- a/addons/gunbag/stringtable.xml +++ b/addons/gunbag/stringtable.xml @@ -13,6 +13,7 @@ Borsa per Armi 枪袋 槍袋 + Bolsa de Arma Gunbag (Tan) @@ -26,6 +27,7 @@ Borsa per Armi (Tan) 枪袋 (黄褐色) 槍袋 (黃褐色) + Bolsa de Arma (Bege) Put weapon into gunbag @@ -39,6 +41,7 @@ Metti l'arma nella borsa per armi 将武器放置枪袋 將武器放置槍袋 + Colocar arma na Bosla de Arma Get weapon out of gunbag @@ -52,6 +55,7 @@ Prendi l'arma dalla borsa per armi 将武器拿出枪袋 將武器拿出槍袋 + Retirar arma da Bolsa de Arma Status @@ -65,6 +69,7 @@ Stato 状态 狀態 + Status Gunbag Empty @@ -78,6 +83,7 @@ Borsa per armi vuota 枪袋为空 槍袋為空 + Bolsa de Arma Vazia diff --git a/addons/hearing/stringtable.xml b/addons/hearing/stringtable.xml index 048445d3fa..d618854cbb 100644 --- a/addons/hearing/stringtable.xml +++ b/addons/hearing/stringtable.xml @@ -284,53 +284,71 @@ Hearing protection + Gehörschutz Protection auditive 聴覚保護 听力保护 聽力保護 Protezione auditiva Ochrona słuchu + Защита слуха + Proteção Auditiva Volume muffling + Lautstärkedämpfung Étouffement des sons 音量低下 降低音量 進低音量 Volume attenuazione Tłumienie głośności + Глушение звука + Abafamento de Volume Earplugs Volume + Lautstärke Ohrenstöpsel 耳栓時の音量 耳塞时音量 耳塞時音量 Volume tappi per le orecchie Głośność Stoperów + Громкость в берушах + Volume do Protetor Auricular Volume when using earplugs. + Lautstärke wenn man Ohrenstöpsel benutzt 耳栓使用時の音量を決定します。 决定带上耳塞时的音量 使用耳塞時音量 Volume audio quandi si indossano i tappi per le orecchie. Głośność podczas używania stoperów. + Громкость при одетых берушах + Volume quando estiver utilizando um Protetor Auricular Unconscious Volume + Lautstärke Bewusstlosigkeit 気絶時の音量 无意识时音量 昏迷時音量 Volume quando incoscente Nieprzytomna Głośność + Громкость без сознания + Volume Inconsciente Volume when unconscious. + Lautstärke während man Bewusstlos ist 気絶時の音量を決定します。 决定处于无意识时的音量 昏迷時使用耳塞的音量 Volume quando incoscente. Głośność podczas bycia nieprzytomnym. + Громкость при потере сознания + Volume enquanto inconsciente diff --git a/addons/hellfire/stringtable.xml b/addons/hellfire/stringtable.xml index 990e5a5b84..b2ec93ea2d 100644 --- a/addons/hellfire/stringtable.xml +++ b/addons/hellfire/stringtable.xml @@ -10,6 +10,8 @@ 設定地獄火模式 Ustaw tryb pocisku Hellfire 헬파이어 모드 세팅 + Установить режим Hellfire + Definir modo de Hellfire diff --git a/addons/hitreactions/stringtable.xml b/addons/hitreactions/stringtable.xml index b727e48514..103ac87ac8 100644 --- a/addons/hitreactions/stringtable.xml +++ b/addons/hitreactions/stringtable.xml @@ -10,6 +10,8 @@ 방아쇠를 당기는 최소한의 피해 Mindestschaden, um Sturz auszulösen Minimalne obrażenie, żeby aktywować spadanie + Минимальный урон для активации падения + Dano Mínimo para ativar queda diff --git a/addons/hot/ACE_GuidanceConfig.hpp b/addons/hot/ACE_GuidanceConfig.hpp index 81f5c69261..f129a6b558 100644 --- a/addons/hot/ACE_GuidanceConfig.hpp +++ b/addons/hot/ACE_GuidanceConfig.hpp @@ -5,6 +5,7 @@ class EGVAR(missileguidance,AttackProfiles) { description = CSTRING(missileType_Description); functionName = QFUNC(attackProfile_WIRE); + onFired = QFUNC(wire_onFired); }; }; class EGVAR(missileguidance,SeekerTypes) { @@ -14,6 +15,7 @@ class EGVAR(missileguidance,SeekerTypes) { description = CSTRING(SACLOS_Description); functionName = QFUNC(seekerType_SACLOS); + onFired = QFUNC(SACLOS_onFired); }; }; diff --git a/addons/hot/CfgAmmo.hpp b/addons/hot/CfgAmmo.hpp index 168386d47f..e591d13aff 100644 --- a/addons/hot/CfgAmmo.hpp +++ b/addons/hot/CfgAmmo.hpp @@ -70,8 +70,6 @@ class CfgAmmo { defaultSeekerLockMode = "LOAL"; seekerLockModes[] = { "LOAL", "LOBL" }; - onFired = QFUNC(onFired); - seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] seekerAngle = 30; // Angle from the shooter's view that can track the missile seekerAccuracy = 1; // seeker accuracy multiplier diff --git a/addons/hot/XEH_PREP.hpp b/addons/hot/XEH_PREP.hpp index 5942a97017..ec59d0f41f 100644 --- a/addons/hot/XEH_PREP.hpp +++ b/addons/hot/XEH_PREP.hpp @@ -1,4 +1,5 @@ PREP(seekerType_SACLOS); PREP(attackProfile_WIRE); -PREP(onFired); +PREP(wire_onFired); +PREP(SACLOS_onFired); diff --git a/addons/hot/functions/fnc_SACLOS_onFired.sqf b/addons/hot/functions/fnc_SACLOS_onFired.sqf new file mode 100644 index 0000000000..7702b330ee --- /dev/null +++ b/addons/hot/functions/fnc_SACLOS_onFired.sqf @@ -0,0 +1,35 @@ +#include "script_component.hpp" +/* + * Author: Brandon (TCVM) + * Sets up SACLOS state arrays (called from missileGuidance's onFired). + * + * Arguments: + * Guidance Arg Array + * + * Return Value: + * None + * + * Example: + * [] call ace_hot_fnc_SACLOS_onFired + * + * Public: No + */ +params ["_firedEH", "", "", "", "_stateParams"]; +_firedEH params ["_shooter","_weapon","","","","","_projectile"]; +_stateParams params ["", "_seekerStateParams"]; + +private _config = ([_projectile] call CBA_fnc_getObjectConfig) >> "ace_missileguidance"; +private _distanceAheadOfMissile = [_config >> "missileLeadDistance", "NUMBER", DEFAULT_LEAD_DISTANCE] call CBA_fnc_getConfigEntry; + +if (_shooter isKindOf "Plane") then { WARNING("SACLOS fired from planes unsupported"); }; + +private _turretPath = [_shooter, _weapon] call CBA_fnc_turretPathWeapon; +private _turretConfig = [_shooter, _turretPath] call CBA_fnc_getTurret; +private _memoryPointGunnerOptics = getText(_turretConfig >> "memoryPointGunnerOptics"); +private _animationSourceBody = getText(_turretConfig >> "animationSourceBody"); +private _animationSourceGun = getText(_turretConfig >> "animationSourceGun"); +_seekerStateParams set [0, _memoryPointGunnerOptics]; +_seekerStateParams set [1, _animationSourceBody]; +_seekerStateParams set [2, _animationSourceGun]; +_seekerStateParams set [3, _distanceAheadOfMissile]; + diff --git a/addons/hot/functions/fnc_attackProfile_WIRE.sqf b/addons/hot/functions/fnc_attackProfile_WIRE.sqf index 8aef8a702b..139939e4f7 100644 --- a/addons/hot/functions/fnc_attackProfile_WIRE.sqf +++ b/addons/hot/functions/fnc_attackProfile_WIRE.sqf @@ -19,7 +19,7 @@ params ["_seekerTargetPos", "_args", "_attackProfileStateParams"]; _args params ["_firedEH"]; _firedEH params ["_shooter","","","","","","_projectile"]; -_attackProfileStateParams params["_maxCorrectableDistance", "_wireCut", "_randomVector", "_crosshairOffset", "_seekerMaxRangeSqr", "_wireCutSource"]; +_attackProfileStateParams params["_maxCorrectableDistance", "_wireCut", "_randomVector", "_crosshairOffset", "_seekerMaxRangeSqr", "", "_wireCutSource"]; private _projectilePos = getPosASL _projectile; diff --git a/addons/hot/functions/fnc_seekerType_SACLOS.sqf b/addons/hot/functions/fnc_seekerType_SACLOS.sqf index 89ee38b696..06245d0708 100644 --- a/addons/hot/functions/fnc_seekerType_SACLOS.sqf +++ b/addons/hot/functions/fnc_seekerType_SACLOS.sqf @@ -25,7 +25,7 @@ _seekerStateParams params ["_memoryPointGunnerOptics", "_animationSourceBody", " private _shooterPos = AGLToASL (_shooter modelToWorld(_shooter selectionPosition _memoryPointGunnerOptics)); private _projPos = getPosASL _projectile; -private _lookDirection = if !(_shooter isKindOf "CAManBase") then { +private _lookDirection = if !(_shooter isKindOf "CAManBase" || {_shooter isKindOf "StaticWeapon"}) then { private _gBody = -deg(_shooter animationPhase _animationSourceBody); private _gGun = deg(_shooter animationPhase _animationSourceGun); diff --git a/addons/hot/functions/fnc_onFired.sqf b/addons/hot/functions/fnc_wire_onFired.sqf similarity index 51% rename from addons/hot/functions/fnc_onFired.sqf rename to addons/hot/functions/fnc_wire_onFired.sqf index 38599f9b6a..3e1ff2d03d 100644 --- a/addons/hot/functions/fnc_onFired.sqf +++ b/addons/hot/functions/fnc_wire_onFired.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" /* * Author: Brandon (TCVM) - * Sets up missile guidance state arrays (called from missileGuidance's onFired). + * Sets up wireGuided state arrays (called from missileGuidance's onFired). * * Arguments: * Guidance Arg Array @@ -10,26 +10,26 @@ * None * * Example: - * [] call ace_hot_fnc_onFired + * [] call ace_hot_fnc_wire_onFired * * Public: No */ params ["_firedEH", "", "", "_seekerParams", "_stateParams"]; _firedEH params ["_shooter","_weapon","","","","","_projectile", "_gunner"]; -_stateParams params ["", "_seekerStateParams", "_attackProfileStateParams"]; -_seekerParams params ["", "", "_seekerMaxRange"]; +_stateParams params ["", "", "_attackProfileStateParams"]; +_seekerParams params ["", "", "_seekerMaxRange", "_seekerMinRange"]; private _config = ([_projectile] call CBA_fnc_getObjectConfig) >> "ace_missileguidance"; private _maxCorrectableDistance = [_config >> "correctionDistance", "NUMBER", DEFAULT_CORRECTION_DISTANCE] call CBA_fnc_getConfigEntry; -private _crosshairOffset = [_config >> "offsetFromCrosshair", "ARRAY", [0, 0, 0]] call CBA_fnc_getConfigEntry; private _maxDistanceSqr = _seekerMaxRange * _seekerMaxRange; -private _distanceAheadOfMissile = [_config >> "missileLeadDistance", "NUMBER", DEFAULT_LEAD_DISTANCE] call CBA_fnc_getConfigEntry; +private _minDistanceSqr = _seekerMinRange * _seekerMinRange; // AI don't know how to use the crosshair offset becauze they dum dum -if ((_gunner != ACE_PLAYER) && {_gunner != (ACE_controlledUAV select 1)}) then { - _crosshairOffset = [0, 0, 0]; +_crosshairOffset = if ((_gunner != ACE_PLAYER) && {_gunner != (ACE_controlledUAV select 1)}) then { + [0, 0, 0]; +} else { + [_config >> "offsetFromCrosshair", "ARRAY", [0, 0, 0]] call CBA_fnc_getConfigEntry }; -if (_shooter isKindOf "Plane") then {WARNING("SACLOS fired from planes unsupported");}; private _turretPath = [_shooter, _weapon] call CBA_fnc_turretPathWeapon; private _turretConfig = [_shooter, _turretPath] call CBA_fnc_getTurret; @@ -41,13 +41,6 @@ _attackProfileStateParams set [1, false]; // _wireCut _attackProfileStateParams set [2, [0, 0, 0]]; // _randomVector _attackProfileStateParams set [3, _crosshairOffset]; // crosshair offset _attackProfileStateParams set [4, _maxDistanceSqr]; // max distance squared used for wire cut -_attackProfileStateParams set [5, _wireCutSource]; - -private _memoryPointGunnerOptics = getText(_turretConfig >> "memoryPointGunnerOptics"); -private _animationSourceBody = getText(_turretConfig >> "animationSourceBody"); -private _animationSourceGun = getText(_turretConfig >> "animationSourceGun"); -_seekerStateParams set [0, _memoryPointGunnerOptics]; -_seekerStateParams set [1, _animationSourceBody]; -_seekerStateParams set [2, _animationSourceGun]; -_seekerStateParams set [3, _distanceAheadOfMissile]; +_attackProfileStateParams set [5, _minDistanceSqr]; +_attackProfileStateParams set [6, _wireCutSource]; diff --git a/addons/hot/stringtable.xml b/addons/hot/stringtable.xml index 56df14fb82..dee2ec4310 100644 --- a/addons/hot/stringtable.xml +++ b/addons/hot/stringtable.xml @@ -7,6 +7,8 @@ Kierowany przewodem Filoguidato ワイヤ有線誘導 + Проводное управление + Guiado por Fio Semi-automatic command to line of sight @@ -14,6 +16,8 @@ Semi-automatyczna komenda do pola widzenia Comando Semi-Automatico via Contatto Visivo(SACLOS) 半自動指令照準線一致誘導方式 + Полуавтоматическое командное наведение по линии визирования (SACLOS) + Comando semi-automático para a linha de visão (SACLOS) Wire-Guided Missile @@ -21,114 +25,170 @@ Pocisk kierowany przewodowo Missile filoguidato ワイヤ有線誘導ミサイル + Ракета с проводным управлением + Míssil Guiado por Fio HOT Missile + Lenkflugkörper Pocisk HOT Missile HOT HOT ミサイル + Ракета HOT + Míssil HOT HOT 1 + HOT 1 HOT 1 HOT 1 HOT 1 + HOT 1 + HOT 1 HOT 2 + HOT 2 HOT 2 HOT 2 HOT 2 + HOT 2 + HOT 2 HOT 2MP + HOT 2MP HOT 2MP HOT 2MP HOT 2MP + HOT 2MP + HOT 2MP HOT 3 + HOT 3 HOT 3 HOT 3 HOT 3 + HOT 3 + HOT 3 Wire-Guided Missile (Anti-Personnel) + Anti Personen Lenkflugkörper Pocisk kierowany przewodowo (przeciwpiechotny) Missile filoguidato antiuomo ワイヤ有線誘導ミサイル (対人) + Ракета с проводным управлением (Противопехотная) + Míssil Guiado por Fio (Anti-Pessoal) 1x HOT 1 [ACE] + 1x HOT 1 [ACE] 1x HOT 1 [ACE] 1x HOT1 [ACE] 1x HOT 1 [ACE] + 1x HOT 1 [ACE] + 1x HOT 1 [ACE] 3x HOT 1 [ACE] + 3x HOT 1 [ACE] 3x HOT 1 [ACE] 3x HOT 1 [ACE] 3x HOT 1 [ACE] + 3x HOT 1 [ACE] + 3x HOT 1 [ACE] 4x HOT 1 [ACE] + 4x HOT 1 [ACE] 4x HOT 1 [ACE] 4x HOT 1 [ACE] 4x HOT 1 [ACE] + 4x HOT 1 [ACE] + 4x HOT 1 [ACE] 1x HOT 2 [ACE] + 1x HOT 2 [ACE] 1x HOT 2 [ACE] 1x HOT 2 [ACE] 1x HOT 2 [ACE] + 1x HOT 2 [ACE] + 1x HOT 2 [ACE] 3x HOT 2 [ACE] + 3x HOT 2 [ACE] 3x HOT 2 [ACE] 3x HOT 2 [ACE] 3x HOT 2 [ACE] + 3x HOT 2 [ACE] + 3x HOT 2 [ACE] 4x HOT 2 [ACE] + 4x HOT 2 [ACE] 4x HOT 2 [ACE] 4x HOT 2 [ACE] 4x HOT 2 [ACE] + 4x HOT 2 [ACE] + 4x HOT 2 [ACE] 1x HOT 2MP [ACE] + 1x HOT 2MP [ACE] 1x HOT 2MP [ACE] 1x HOT 2MP [ACE] 1x HOT 2MP [ACE] + 1x HOT 2MP [ACE] + 1x HOT 2MP [ACE] 3x HOT 2MP [ACE] + 3x HOT 2MP [ACE] 3x HOT 2MP [ACE] 3x HOT 2MP [ACE] 3x HOT 2MP [ACE] + 3x HOT 2MP [ACE] + 3x HOT 2MP [ACE] 4x HOT 2MP [ACE] + 4x HOT 2MP [ACE] 4x HOT 2MP [ACE] 4x HOT 2MP [ACE] 4x HOT 2MP [ACE] + 4x HOT 2MP [ACE] + 4x HOT 2MP [ACE] 1x HOT 3 [ACE] + 1x HOT 3 [ACE] 1x HOT 3 [ACE] 1x HOT 3 [ACE] 1x HOT 3 [ACE] + 1x HOT 3 [ACE] + 1x HOT 3 [ACE] 4x HOT 3 [ACE] + 4x HOT 3 [ACE] 4x HOT 3 [ACE] 4x HOT 3 [ACE] 4x HOT 3 [ACE] + 4x HOT 3 [ACE] + 4x HOT 3 [ACE] 3x HOT 3 [ACE] + 3x HOT 3 [ACE] 3x HOT 3 [ACE] 3x HOT 3 [ACE] 3x HOT 3 [ACE] + 3x HOT 3 [ACE] + 3x HOT 3 [ACE] diff --git a/addons/interact_menu/XEH_preInit.sqf b/addons/interact_menu/XEH_preInit.sqf index 08fa9701cd..4266e9f805 100644 --- a/addons/interact_menu/XEH_preInit.sqf +++ b/addons/interact_menu/XEH_preInit.sqf @@ -74,4 +74,38 @@ GVAR(lastTimeSearchedActions) = -1000; // Init zeus menu [] call FUNC(compileMenuZeus); +// Handle addActionToClass with Inheritance flag set (CAManBase actions are seperated for speed) +GVAR(inheritedActionsAll) = []; +GVAR(inheritedClassesAll) = []; +GVAR(inheritedActionsMan) = []; +GVAR(inheritedClassesMan) = []; + +["All", "InitPost", { + BEGIN_COUNTER(InitPost); + params ["_object"]; + private _type = typeOf _object; + + if (GVAR(inheritedClassesAll) pushBackUnique _type == -1) exitWith { END_COUNTER(InitPost); }; + + { + _x params ["_objectType", "_typeNum", "_parentPath", "_action"]; + if (_object isKindOf _objectType) then { + [_type, _typeNum, _parentPath, _action] call FUNC(addActionToClass); + }; + } forEach GVAR(inheritedActionsAll); + END_COUNTER(InitPost); +}] call CBA_fnc_addClassEventHandler; +["CAManBase", "InitPost", { + BEGIN_COUNTER(InitPost); + params ["_object"]; + private _type = typeOf _object; + + if (GVAR(inheritedClassesMan) pushBackUnique _type == -1) exitWith { END_COUNTER(InitPost); }; + { + _x params ["_typeNum", "_parentPath", "_action"]; + [_type, _typeNum, _parentPath, _action] call FUNC(addActionToClass); + } forEach GVAR(inheritedActionsMan); + END_COUNTER(InitPost); +}] call CBA_fnc_addClassEventHandler; + ADDON = true; diff --git a/addons/interact_menu/config.cpp b/addons/interact_menu/config.cpp index 687d644924..ff29cfc850 100644 --- a/addons/interact_menu/config.cpp +++ b/addons/interact_menu/config.cpp @@ -23,5 +23,12 @@ class CfgPatches { #include "ACE_Settings.hpp" class ACE_Extensions { - extensions[] += {"ace_break_line", "ace_parse_imagepath"}; + class ace_break_line { + windows = 1; + client = 1; + }; + class ace_parse_imagepath { + windows = 1; + client = 1; + }; }; diff --git a/addons/interact_menu/functions/fnc_addActionToClass.sqf b/addons/interact_menu/functions/fnc_addActionToClass.sqf index 20c229bfc6..69425ea047 100644 --- a/addons/interact_menu/functions/fnc_addActionToClass.sqf +++ b/addons/interact_menu/functions/fnc_addActionToClass.sqf @@ -25,21 +25,24 @@ if (!params [["_objectType", "", [""]], ["_typeNum", 0, [0]], ["_parentPath", [] ERROR("Bad Params"); [] }; -TRACE_4("params",_objectType,_typeNum,_parentPath,_action); +TRACE_4("addActionToClass",_objectType,_typeNum,_parentPath,_action); if (param [4, false, [false]]) exitwith { - if (isNil QGVAR(inheritedActions)) then {GVAR(inheritedActions) = [];}; - private _index = GVAR(inheritedActions) pushBack [[], _typeNum, _parentPath, _action]; - private _initEH = compile format [' - params ["_object"]; - private _typeOf = typeOf _object; - (GVAR(inheritedActions) select %1) params ["_addedClasses", "_typeNum", "_parentPath", "_action"]; - if (_typeOf in _addedClasses) exitWith {}; - _addedClasses pushBack _typeOf; - [_typeOf, _typeNum, _parentPath, _action] call FUNC(addActionToClass); - ', _index]; - TRACE_2("Added inheritable action",_objectType,_index); - [_objectType, "init", _initEH, true, [], true] call CBA_fnc_addClassEventHandler; + BEGIN_COUNTER(addAction); + if (_objectType == "CAManBase") then { + GVAR(inheritedActionsMan) pushBack [_typeNum, _parentPath, _action]; + { + [_x, _typeNum, _parentPath, _action] call FUNC(addActionToClass); + } forEach GVAR(inheritedClassesMan); + } else { + GVAR(inheritedActionsAll) pushBack [_objectType, _typeNum, _parentPath, _action]; + { + if (_x isKindOf _objectType) then { + [_x, _typeNum, _parentPath, _action] call FUNC(addActionToClass); + }; + } forEach GVAR(inheritedClassesAll); + }; + END_COUNTER(addAction); // Return the full path (_parentPath + [_action select 0]) diff --git a/addons/interact_menu/functions/fnc_compileMenu.sqf b/addons/interact_menu/functions/fnc_compileMenu.sqf index 2f68d490b8..bac9d42fff 100644 --- a/addons/interact_menu/functions/fnc_compileMenu.sqf +++ b/addons/interact_menu/functions/fnc_compileMenu.sqf @@ -122,7 +122,7 @@ private _actions = [_actionsCfg, 0] call _recurseFnc; // ace_interaction_fnc_addPassengerAction expects ACE_MainActions to be first // Other mods can change the order that configs are added, so we should verify this now and resort if needed -if (_objectType isKindOf "CaManBase") then { +if (_objectType isKindOf "CAManBase") then { if ((((_actions select 0) select 0) select 0) != "ACE_MainActions") then { INFO_1("ACE_MainActions not first for man [%1]",_objectType); private _mainActions = []; diff --git a/addons/interact_menu/stringtable.xml b/addons/interact_menu/stringtable.xml index 2e29db71e5..8b5fdaa551 100644 --- a/addons/interact_menu/stringtable.xml +++ b/addons/interact_menu/stringtable.xml @@ -448,11 +448,14 @@ Selector Color + Farbauswahl セレクターの色 选择器颜色 選單的顏色 Controllo Settore Kolor wybierającego + Цвет селектора + Cor do Seletor diff --git a/addons/interaction/stringtable.xml b/addons/interaction/stringtable.xml index 50b023f95d..200658779b 100644 --- a/addons/interaction/stringtable.xml +++ b/addons/interaction/stringtable.xml @@ -10,6 +10,8 @@ インタラクション 상호작용 Interakcja + Взаимодействие + Interação Interactions @@ -21,7 +23,7 @@ Взаимодействия Cselekvések Interazioni - Interaçãoes + Interações インタラクション 상호작용 互动 @@ -450,7 +452,7 @@ Odejdź! Jděte pryč! Allez-vous-en ! - Уходите отсюда! + Уйдите отсюда! Tűnés! Vá Embora! Via di qui! @@ -482,12 +484,13 @@ Aussteigen! Sal del vehículo! Sortez ! - Выходи + Выходи! Vystupte 降りろ 나가 出去 出去 + Saia! Team Management @@ -843,11 +846,13 @@ Flip + Umdrehen Перевернуть ひっくり返す Gira Przewróć + Virar Interact @@ -954,6 +959,8 @@ 关闭负面评价 부정행위 가중치 사용안함 Wyłącz negatywną ocenę + Отключить отрицательный рейтинг + Desativar avaliação negativa 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. @@ -964,6 +971,8 @@ 玩家是否会收到负面评价? 当本功能开启时玩家只会接收到正面评价,所以当玩家做出击杀友军AI、毁坏友军装备或杀害小队伙伴都不会收到负面评价。 플레이어의 부정행위 가중치를 계산합니까? 활성화된 플레이어는 높은 레이팅을 가질때, 아군의 장비나 병력을 사격해도 아군 AI의 사격을 받지 않습니다. Czy powinni gracze otrzymywać negatywną ocenę? Kiedy aktywowani gracze otrzymuję wyłącznie pozytywną ocenę, która zapobiega ognia przyjaznego SI podczas niszczenia przyjaznego wyposażenia lub zabijaniu członków drużyny. + Должны ли игроки получать отрицательный рейтинг? Когда включено, игроки получают только положительный рейтинг, что предотвращает дружественный огонь от ИИ при уничтожении дружественного оборудования или убийстве членов команды. + Jogadores devem receber uma avaliação negativa? Quando ativado, os jogadores estão recebendo avaliações positivas, prevenindo que IA amigável atire quando destruir algum equipamento aliado ou matar membros de equipe. Team management allows color allocation for team members, taking team command and joining/leaving teams. @@ -1088,6 +1097,7 @@ Pull out body + Person herausziehen Вытащить тело 身体を引き出す Estrai il corpo @@ -1095,6 +1105,7 @@ 拿出屍體 拿出尸体 Wyciągnij ciało + Retirar Corpo Smash windshield @@ -1106,6 +1117,7 @@ Szélvédő széttörése フロントガラスを破る Sfonda il parabrezza + Quebrar pára-brisa diff --git a/addons/inventory/XEH_preStart.sqf b/addons/inventory/XEH_preStart.sqf index ae4ce6500c..18999d638e 100644 --- a/addons/inventory/XEH_preStart.sqf +++ b/addons/inventory/XEH_preStart.sqf @@ -36,14 +36,10 @@ _grenades_ItemList = _grenades_ItemList arrayIntersect _grenades_ItemList; uiNamespace setVariable [QGVAR(Grenades_ItemList), _grenades_ItemList]; // generate list of medical items -private _medical_ItemList = []; - +private _medical_ItemList = ["FirstAidKit", "Medikit"]; { _medical_ItemList append getArray (_x >> "items"); -} forEach ( - ("true" configClasses (configFile >> QEGVAR(Medical,Actions) >> "Basic")) + - ("true" configClasses (configFile >> QEGVAR(Medical,Actions) >> "Advanced")) -); +} forEach ("true" configClasses (configFile >> QEGVAR(medical_treatment,Actions))); // remove all numbers from list _medical_ItemList = _medical_ItemList select {_x isEqualType ""}; diff --git a/addons/laser/functions/fnc_addLaserTarget.sqf b/addons/laser/functions/fnc_addLaserTarget.sqf index 48a98353e9..2cf99a5311 100644 --- a/addons/laser/functions/fnc_addLaserTarget.sqf +++ b/addons/laser/functions/fnc_addLaserTarget.sqf @@ -31,7 +31,7 @@ _vehicle setVariable [QGVAR(targetObject), _targetObject, true]; private _laserMethod = QFUNC(findLaserSource); private _vehicleSourceSelection = ""; -if (_vehicle isKindOf "CaManBase") then { +if (_vehicle isKindOf "CAManBase") then { _vehicleSourceSelection = "pilot"; } else { { // Go through turrets on vehicle and find the laser diff --git a/addons/laser/stringtable.xml b/addons/laser/stringtable.xml index 016c8f5c8a..e96943ff8b 100644 --- a/addons/laser/stringtable.xml +++ b/addons/laser/stringtable.xml @@ -11,6 +11,8 @@ Contatore di Simulazione della Dispersione del Laser 雷射散射模拟计算 雷射散射模擬計算 + Число симуляций рассеивания лазерного луча + Contador da Simulação de Dispersão de Laser Laser Code diff --git a/addons/laserpointer/CfgJointRails.hpp b/addons/laserpointer/CfgJointRails.hpp index 7583bd03b5..da7aee71b5 100644 --- a/addons/laserpointer/CfgJointRails.hpp +++ b/addons/laserpointer/CfgJointRails.hpp @@ -6,3 +6,11 @@ class asdg_FrontSideRail: asdg_SlotInfo { ACE_acc_pointer_green_IR = 1; }; }; + +class PointerSlot_Rail: PointerSlot { + class compatibleItems { + ACE_acc_pointer_red = 1; + ACE_acc_pointer_green = 1; + ACE_acc_pointer_green_IR = 1; + }; +}; diff --git a/addons/magazinerepack/stringtable.xml b/addons/magazinerepack/stringtable.xml index 3145b220eb..48bb15ff77 100644 --- a/addons/magazinerepack/stringtable.xml +++ b/addons/magazinerepack/stringtable.xml @@ -3,12 +3,15 @@ Magazine Repack + Magazine umpacken Riempimento Caricatori 重新整理彈匣 重新整理弹匣 弾倉詰め替え 탄약 채우기 Przepakowywanie magazynków + Перепаковка Магазинов + Preenchimento de Carregador Time per round @@ -19,6 +22,8 @@ 弾頭毎の所有時間 구경 당 시간 Czas na nabój + Время на патрон + Tempo por projétil Time per magazine @@ -29,6 +34,8 @@ 弾倉毎の所有時間 탄창 당 시간 Czas na magazynek + Время на магазин + Tempo por carregador Time per belt link @@ -39,6 +46,8 @@ ベルトリンク毎の所有時間 탄약띠 당 시간 Czas na taśmę + Время на звено ленты + Tempo por carregador de cinto Repack Magazines diff --git a/addons/main/config.cpp b/addons/main/config.cpp index 81b5e7ce3d..4852b9ff16 100644 --- a/addons/main/config.cpp +++ b/addons/main/config.cpp @@ -7,7 +7,7 @@ class CfgPatches { weapons[] = {}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = { - "A3_Data_F_Tank_Loadorder", + "A3_Data_F_Enoch_Loadorder", "A3_Data_F_Mod_Loadorder", // CBA "cba_ui", diff --git a/addons/main/script_mod.hpp b/addons/main/script_mod.hpp index c368490e8d..6a38897d47 100644 --- a/addons/main/script_mod.hpp +++ b/addons/main/script_mod.hpp @@ -5,12 +5,13 @@ #include "script_version.hpp" -#define VERSION MAJOR.MINOR.PATCHLVL.BUILD -#define VERSION_AR MAJOR,MINOR,PATCHLVL,BUILD +#define VERSION MAJOR.MINOR +#define VERSION_STR MAJOR.MINOR.PATCHLVL.BUILD +#define VERSION_AR MAJOR,MINOR,PATCHLVL,BUILD // MINIMAL required version for the Mod. Components can specify others.. -#define REQUIRED_VERSION 1.88 -#define REQUIRED_CBA_VERSION {3,11,1} +#define REQUIRED_VERSION 1.94 +#define REQUIRED_CBA_VERSION {3,11,2} #ifdef COMPONENT_BEAUTIFIED #define COMPONENT_NAME QUOTE(ACE3 - COMPONENT_BEAUTIFIED) diff --git a/addons/map/stringtable.xml b/addons/map/stringtable.xml index d2cc5e90d0..33110569e9 100644 --- a/addons/map/stringtable.xml +++ b/addons/map/stringtable.xml @@ -512,6 +512,8 @@ Disablita BFT 关闭友军踪迹 關閉友軍蹤跡 + Отключить BFT + Desativar BFT Always disable Blue Force Tracking for this group. @@ -523,6 +525,8 @@ Disabilita sempre il Blue Force Tracking per questo gruppo. 对此小队永远关闭友军踪迹显示 對此小隊永遠關閉友軍蹤跡顯示 + Всегда отключать Blue Force Tracking для этой группы + Sempre desativar Rastreio Blue Force (BFT) para esse grupo. diff --git a/addons/maptools/CfgVehicles.hpp b/addons/maptools/CfgVehicles.hpp index 2e5663e251..5ab3eac165 100644 --- a/addons/maptools/CfgVehicles.hpp +++ b/addons/maptools/CfgVehicles.hpp @@ -5,14 +5,14 @@ class CfgVehicles { class ACE_MapGpsShow { displayName = CSTRING(MapGpsShow); condition = QUOTE((!GVAR(mapGpsShow)) && {call FUNC(canUseMapGPS)}); - statement = QUOTE(GVAR(mapGpsShow) = true; [GVAR(mapGpsShow)] call FUNC(openMapGps)); + statement = QUOTE(GVAR(mapGpsShow) = true;); exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}; showDisabled = 0; }; class ACE_MapGpsHide { displayName = CSTRING(MapGpsHide); condition = QUOTE((GVAR(mapGpsShow)) && {call FUNC(canUseMapGPS)}); - statement = QUOTE(GVAR(mapGpsShow) = false; [GVAR(mapGpsShow)] call FUNC(openMapGps)); + statement = QUOTE(GVAR(mapGpsShow) = false;); exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}; showDisabled = 0; }; diff --git a/addons/maptools/MapGpsUI.hpp b/addons/maptools/MapGpsUI.hpp deleted file mode 100644 index cd0a418465..0000000000 --- a/addons/maptools/MapGpsUI.hpp +++ /dev/null @@ -1,80 +0,0 @@ -#define GUI_GRID_X (0) -#define GUI_GRID_Y (0) -#define GUI_GRID_W (0.025) -#define GUI_GRID_H (0.04) - -#define ST_LEFT 0x00 -#define ST_RIGHT 0x01 -#define ST_CENTER 0x02 - -#define W_gps 0.4025 -#define H_gps 0.25 -#define X_gps safeZoneX + safeZoneW - 1.1 * W_gps -#define Y_gps safeZoneY + safeZoneH - 1.2 * H_gps - -class RscTitles { - class RscACE_MapGps { - idd = 9855; - movingEnable = 1; - duration = 3600; - fadein = 0; - fadeout = 0; - onLoad = QUOTE(uiNamespace setVariable [ARR_2(QUOTE(QGVAR(ui_mapGpsDisplay)), _this select 0)];); - class controls { - class back:RscPicture { - x = X_gps; - y = Y_gps; - w = W_gps; - h = H_gps; - text = QPATHTOF(UI\mapGps.paa); - colorBackground[] = {1, 1, 1, 1}; - }; - class heading: RscText{ - idc = 913590; - x = X_gps + W_gps * 0.225; - y = Y_gps + H_gps * 0.12; - w = W_gps * 0.2; - h = H_gps * 0.16; - style = ST_LEFT; - text = "225"; - colorBackground[] = {0,0,0,0}; - colorText[] = {0.247,0.251,0.157,1}; - shadowColo[] = {0,0,0,0}; - // EtelkaNarrowMediumPro broke with 1.72 hotfix, can revert back to that font if fixed (following 3 uses of PuristaSemibold) - font = "PuristaSemibold"; - shadow = 0; - sizeEx = 0.042; - }; - class altitude: RscText{ - idc = 913591; - x = X_gps + W_gps * 0.575; - y = Y_gps + H_gps * 0.12; - w = W_gps * 0.2; - h = H_gps * 0.16; - style = ST_RIGHT; - text = "55 m"; - colorBackground[] = {0,0,0,0}; - colorText[] = {0.247,0.251,0.157,1}; - shadowColo[] = {0,0,0,0}; - font = "PuristaSemibold"; - shadow = 0; - sizeEx = 0.042; - }; - class coordinates: RscText{ - idc = 913592; - x = X_gps + W_gps * 0.15; - y = Y_gps + H_gps * 0.33; - w = W_gps * 0.7; - h = H_gps * 0.35; - style = ST_CENTER; - text = "012.3 115.1"; - colorBackground[] = {0,0,0,0}; - colorText[] = {0.247,0.251,0.157,1}; - shadowColo[] = {0,0,0,0}; - font = "PuristaSemibold"; - shadow = 0; - sizeEx = 0.1; - }; - }; - }; -}; diff --git a/addons/maptools/RscDisplayMainMap.hpp b/addons/maptools/RscDisplayMainMap.hpp new file mode 100644 index 0000000000..db54ab6bf8 --- /dev/null +++ b/addons/maptools/RscDisplayMainMap.hpp @@ -0,0 +1,89 @@ +class RscDisplayMainMap { + class objects { + class GVAR(MapGpsDisplay): RscObject { + show = 0; + idc = 913589; + type = 82; + model = QPATHTOF(data\MapGpsDisplay.p3d); + /* + 1.000 - normal model + memory - has 4 points in selection "deviceScreen" and then those 4 as individual "deviceScreen tl", "deviceScreen br", "deviceScreen b'", "deviceScreen br" + geometry - has a simpe box with a name selection component01 (needed to make it dragable) + */ + scale = 0.333; + direction[] = {0,1,0}; + up[] = {0,0,-1}; + x = 0.9; + y = 0.9; + z = 0.2; + xBack = 0.9; + yBack = 0.9; + zBack = 0.3; + inBack = 1; + enableZoom = 1; + zoomDuration = 0.001; + class Areas { + class deviceScreen { + selection = "deviceScreen"; + class controls { + class Picture: RscPicture { + text = QPATHTOF(UI\MapGpsDisplay_background_ca.paa); + // gets displayed in game a little bit washed out depending on rotation angle + x = 0; + y = 0; + w = 1; + h = 0.77; + }; + + class heading: RscText { + idc = 913590; + x = 0.15; + y = 0; + w = 0.35; + h = 0.2; + style = 0; // ST_LEFT + text = "225"; + colorBackground[] = {0,0,0,0}; + colorText[] = {0.1235,0.1255,0.0785,1}; + shadowColor[] = {0,0,0,0}; + // EtelkaNarrowMediumPro broke with 1.72 hotfix, can revert back to that font if fixed (following 3 uses of PuristaSemibold) [ still broken ] + font = "PuristaSemibold"; + shadow = 0; + sizeEx = 0.18; + }; + class altitude: RscText{ + idc = 913591; + x = 0.5; + y = 0; + w = 0.35; + h = 0.2; + style = 1; // ST_RIGHT + text = "55 m"; + colorBackground[] = {0,0,0,0}; + colorText[] = {0.1235,0.1255,0.0785,1}; + shadowColor[] = {0,0,0,0}; + font = "PuristaSemibold"; + shadow = 0; + sizeEx = 0.18; + }; + class coordinates: RscText{ + idc = 913592; + x = 0; + y = 0.225; + w = 1; + h = 0.35; + style = 2; // ST_CENTER + text = "12345 12345"; + colorBackground[] = {0,0,0,0}; + colorText[] = {0.1235,0.1255,0.0785,1}; + shadowColor[] = {0,0,0,0}; + font = "PuristaSemibold"; + shadow = 0; + sizeEx = 0.333; + }; + }; + }; + }; + }; + }; +}; diff --git a/addons/maptools/UI/MapGpsDisplay_background_ca.paa b/addons/maptools/UI/MapGpsDisplay_background_ca.paa new file mode 100644 index 0000000000..fedae61df5 Binary files /dev/null and b/addons/maptools/UI/MapGpsDisplay_background_ca.paa differ diff --git a/addons/maptools/UI/mapGps.paa b/addons/maptools/UI/mapGps.paa deleted file mode 100644 index defcdbc63b..0000000000 Binary files a/addons/maptools/UI/mapGps.paa and /dev/null differ diff --git a/addons/maptools/XEH_PREP.hpp b/addons/maptools/XEH_PREP.hpp index eac6947431..cf193698e5 100644 --- a/addons/maptools/XEH_PREP.hpp +++ b/addons/maptools/XEH_PREP.hpp @@ -5,6 +5,5 @@ PREP(drawLinesOnRoamer); PREP(handleMouseButton); PREP(handleMouseMove); PREP(isInsideMapTool); -PREP(openMapGps); PREP(openMapGpsUpdate); PREP(updateMapToolMarkers); diff --git a/addons/maptools/XEH_postInitClient.sqf b/addons/maptools/XEH_postInitClient.sqf index ddde7063cc..c7dceacd75 100644 --- a/addons/maptools/XEH_postInitClient.sqf +++ b/addons/maptools/XEH_postInitClient.sqf @@ -6,6 +6,7 @@ if (!hasInterface) exitWith {}; // Init variables GVAR(mapGpsShow) = true; +GVAR(mapGpsNextUpdate) = -1; GVAR(mapTool_Shown) = 0; GVAR(mapTool_pos) = [0,0]; @@ -19,18 +20,12 @@ GVAR(mapTool_isRotating) = false; ((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", {_this call FUNC(updateMapToolMarkers);}]; + ((findDisplay 12) displayCtrl 51) ctrlAddEventHandler ["Draw", {call FUNC(updateMapToolMarkers); call FUNC(openMapGpsUpdate);}]; }, []] call CBA_fnc_waitUntilAndExecute; ["visibleMap", { params ["", "_mapOn"]; - if (_mapOn) then { - // Show GPS if required - [GVAR(mapGpsShow)] call FUNC(openMapGps); - } else { - // Hide GPS - [false] call FUNC(openMapGps); - + if (!_mapOn) then { // Handle closing map in middle of line drawing (it's never created) GVAR(freedrawing) = false; }; diff --git a/addons/maptools/config.cpp b/addons/maptools/config.cpp index e94ec2edcd..40d532a0c1 100644 --- a/addons/maptools/config.cpp +++ b/addons/maptools/config.cpp @@ -26,7 +26,7 @@ class RscButtonMenu; class RscEdit; #include "ACE_Settings.hpp" -#include "MapGpsUI.hpp" #include "CfgEventHandlers.hpp" #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" +#include "RscDisplayMainMap.hpp" diff --git a/addons/maptools/data/MapGpsDisplay.p3d b/addons/maptools/data/MapGpsDisplay.p3d new file mode 100644 index 0000000000..b6cc1b3a71 Binary files /dev/null and b/addons/maptools/data/MapGpsDisplay.p3d differ diff --git a/addons/maptools/functions/fnc_canUseMapGPS.sqf b/addons/maptools/functions/fnc_canUseMapGPS.sqf index 80f2541cab..5de3546d9c 100644 --- a/addons/maptools/functions/fnc_canUseMapGPS.sqf +++ b/addons/maptools/functions/fnc_canUseMapGPS.sqf @@ -10,7 +10,7 @@ * Boolean * * Example: - * call ACE_map_fnc_canUseMapGPS + * call ACE_maptools_fnc_canUseMapGPS * * Public: No */ diff --git a/addons/maptools/functions/fnc_handleMouseButton.sqf b/addons/maptools/functions/fnc_handleMouseButton.sqf index 7c2946abae..4e1c124b2a 100644 --- a/addons/maptools/functions/fnc_handleMouseButton.sqf +++ b/addons/maptools/functions/fnc_handleMouseButton.sqf @@ -24,8 +24,10 @@ TRACE_2("params",_dir,_params); if ((_button == 0) && {GVAR(freedrawing) || _ctrlKey}) exitWith { if (GVAR(freedrawing) && {_dir == 0}) then { GVAR(freedrawing) = false; - GVAR(drawPosEnd) = _control ctrlMapScreenToWorld [_screenPosX, _screenPosY]; - TRACE_2("Ending Line",GVAR(freedrawing),GVAR(drawPosEnd)); + 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); diff --git a/addons/maptools/functions/fnc_openMapGps.sqf b/addons/maptools/functions/fnc_openMapGps.sqf deleted file mode 100644 index 96be3f6bd2..0000000000 --- a/addons/maptools/functions/fnc_openMapGps.sqf +++ /dev/null @@ -1,28 +0,0 @@ -#include "script_component.hpp" -/* - * Author: esteldunedain - * Opens or closes the gps on the map screen, showing coordinates - * - * Arguments: - * 0: Open GPS? - * - * Return Value: - * None - * - * Example: - * [true] call ACE_maptools_fnc_openMapGps - * - * Public: No - */ - -params ["_shouldOpenGps"]; - -private _isOpen = !(isNull (uiNamespace getVariable [QGVAR(ui_mapGpsDisplay), displayNull])); - -if (_shouldOpenGps && {"ItemGPS" in assignedItems ACE_player} && {!_isOpen}) then { - ("RscACE_MapGps" call BIS_fnc_rscLayer) cutRsc ["RscACE_MapGps","PLAIN"]; - - [FUNC(openMapGpsUpdate), 0.5, []] call CBA_fnc_addPerFrameHandler; //update bearing/altitude every 0.5 sec (ticktime) -} else { - ("RscACE_MapGps" call BIS_fnc_rscLayer) cutText ["","PLAIN"]; -}; diff --git a/addons/maptools/functions/fnc_openMapGpsUpdate.sqf b/addons/maptools/functions/fnc_openMapGpsUpdate.sqf index 84cb3f17a4..646b5df2e0 100644 --- a/addons/maptools/functions/fnc_openMapGpsUpdate.sqf +++ b/addons/maptools/functions/fnc_openMapGpsUpdate.sqf @@ -1,30 +1,34 @@ #include "script_component.hpp" /* - * Author: esteldunedain - * update gps display + * Author: esteldunedain, PabstMirror + * update gps display, called from main map's draw * * Arguments: - * Something + * 0: Map ctrl * * Return Value: * None * * Example: - * call ACE_maptools_fnc_openMapGpsUpdate + * [findDisplay 12 displayCtrl 51] call ACE_maptools_fnc_openMapGpsUpdate; * * Public: No */ -if ((!("ItemGPS" in assigneditems ACE_player)) || {isNull (uiNamespace getVariable [QGVAR(ui_mapGpsDisplay), displayNull])}) exitWith { - ("RscACE_MapGps" call BIS_fnc_rscLayer) cutText ["","PLAIN"]; // Close GPS RSC - [(_this select 1)] call CBA_fnc_removePerFrameHandler; // Remove frameHandler -}; -disableSerialization; +params ["_mapCtrl"]; +private _mapDisplay = ctrlParent _mapCtrl; -private _mapGpsDisplay = uiNamespace getVariable [QGVAR(ui_mapGpsDisplay), displayNull]; -private _ctrl = _mapGpsDisplay displayCtrl 913590; +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 = _mapGpsDisplay displayCtrl 913591; +_ctrl = _mapDisplay displayCtrl 913591; _ctrl ctrlSetText str (round ((getPosASL ACE_player) select 2) + EGVAR(common,mapAltitude)); // Set Altitude -_ctrl = _mapGpsDisplay displayCtrl 913592; +_ctrl = _mapDisplay displayCtrl 913592; _ctrl ctrlSetText mapGridPosition ACE_player; // Set grid cords diff --git a/addons/maptools/stringtable.xml b/addons/maptools/stringtable.xml index f0fdd8f186..3fee4de5ad 100644 --- a/addons/maptools/stringtable.xml +++ b/addons/maptools/stringtable.xml @@ -188,6 +188,7 @@ Ruota Strumenti di Mappatura 选转地图工具的按键 選轉地圖工具的按鍵 + Tecla para girar Ferramentas de Mapa Modifier key to allow rotating map tools @@ -200,6 +201,7 @@ Tasto modifica per consentire strumenti di mappatura rotanti 修改旋转地图工具的按键 修改旋轉地圖工具的按鍵 + Tecla de Modificador para permitir girar as ferramentas de mapa Draw straight lines with maptools @@ -211,6 +213,8 @@ Disegna linee dritte con gli strumenti di mappatura 使用地图工具来绘制直线 使用地圖工具來繪製直線 + Прямые линии с инструментами карты + Desenhar linhas retas com as ferramentas de mapa Draw on the edge of maptools to draw straight lines. Note: Must hover at midpoint to delete. @@ -222,6 +226,8 @@ Disegna sul bordo degli strumenti di mappatura per disegnare linee dritte. Nota: Deve spostarsi al centro per essere cancellato. 使用地图工具的边缘来绘制直线。备注: 要删除直线时,请把滑鼠移动到该线条的中央即可删除该线。 使用地圖工具的邊緣來繪製直線。備註: 要刪除直線時,請把滑鼠移動到該線條的中央即可刪除該線 + Рисуйте по краю инструмента карты, чтобы провести прямые линии. Примечание: при удалении линии размещайте курсор над ее серединой + Desenhe no canto da ferramenta de mapa para desenhar linhas retas. Observação: Sobreponha o meio com o mouse para deletar. diff --git a/addons/markers/stringtable.xml b/addons/markers/stringtable.xml index 4c1e4d1c3b..ccd1bbdb94 100644 --- a/addons/markers/stringtable.xml +++ b/addons/markers/stringtable.xml @@ -26,6 +26,8 @@ 标志 맵마커 Znaczniki + Маркеры + Marcadores Allow moving markers for @@ -36,6 +38,8 @@ 谁可以移动标志 Permetti di spostare i marcatori a: Zezwól na poruszanie znaczników dla + Разрешить перемещение маркеров для + Permitir que movam marcadores Restricts which players are able to move markers while holding the Alt key. @@ -46,6 +50,8 @@ 设定谁可以透过按住Alt键来移动标志。 Limita quali giocatori possono spostare i marcatori mentre premono 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. Nobody @@ -56,6 +62,8 @@ 没有人 Nessuno Nikt + Никого + Ninguém All players @@ -66,6 +74,8 @@ 所有玩家 모든 플레이어 Wszyscy gracze + Всех игроков + Todos jogadores Admins @@ -76,6 +86,8 @@ 管理员 관리자 Administratorzy + Админов + Admins Group leaders @@ -86,6 +98,8 @@ 小队长 분대장 Przywódcy grup + Лидеров групп + Líderes de grupo Group leaders and Admins @@ -96,12 +110,16 @@ 小队长与管理员 분대장과 관리자 Przywódcy grup i Administratorzy + Лидеров групп и Админов + Líderes de grupo e Admins Creator Ersteller 設置者 Twórca + Создателя + Criador diff --git a/addons/maverick/stringtable.xml b/addons/maverick/stringtable.xml index 4b0a83cc94..a0ca458c08 100644 --- a/addons/maverick/stringtable.xml +++ b/addons/maverick/stringtable.xml @@ -11,6 +11,8 @@ AGM-65"小牛"空地L型,雷射导引对地导弹 AGM-65 Maverick L, 레이저 유도 대지 미사일 AGM-65 Maverick L, Kierowany laserowo pocisk powietrze-ziemia + AGM-65 Maverick L, ракета Воздух-Земля с лазерным наведением + AGM-65 Maverick L, Míssil Anti Chão Guiado a Laser AGM-65 Maverick L [ACE] @@ -21,6 +23,8 @@ AGM-65"小牛"空地L型 [ACE] AGM-65 Maverick L [ACE] AGM-65 Maverick L [ACE] + AGM-65 Maverick L [ACE] + AGM-65 Maverick L [ACE] 2x AGM-65 Maverick L [ACE] @@ -31,6 +35,8 @@ 2x AGM-65"小牛"空地L型 [ACE] 2x AGM-65 Maverick L [ACE] 2x AGM-65 Maverick L [ACE] + 2x AGM-65 Maverick L [ACE] + 2x AGM-65 Maverick L [ACE] 3x AGM-65 Maverick L [ACE] @@ -41,6 +47,8 @@ 3x AGM-65"小牛"空地L型 [ACE] 3x AGM-65 Maverick L [ACE] 3x AGM-65 Maverick L [ACE] + 3x AGM-65 Maverick L [ACE] + 3x AGM-65 Maverick L [ACE] Laser Guided @@ -51,6 +59,8 @@ 雷射导引 레이저 유도 Kierowany laserowo + С лазерным наведением + Guiado a laser Kh-25ML, Laser Guided Air-to-Ground-Missile @@ -61,6 +71,8 @@ Kh-25ML、レーザー誘導対地ミサイル Kh-25ML, a Guida Laser Missile Aria-Terra Kh-25ML, Kierowany laserowo pocisk powietrze-ziemia + Х-25МЛ, ракета Воздух-Земля с лазерным наведением + Kh-25ML, Míssil Ar para Chão Guiado a Laser 1x Kh-25ML [ACE] @@ -72,6 +84,7 @@ 1x Kh-25ML [ACE] 1x Kh-25ML [ACE] 1x Kh-25ML [ACE] + 1x Kh-25ML [ACE] @@ -84,6 +97,8 @@ AGM-65"小牛"飞弹L型 AGM-65 Maverick L AGM-65 Maverick L + AGM-65 Maverick L + AGM-65 Maverick L Kh-25ML @@ -95,6 +110,7 @@ Kh-25ML Kh-25ML Kh-25ML + Kh-25ML diff --git a/addons/medical/CfgVehicles.hpp b/addons/medical/CfgVehicles.hpp index 424059c8e1..60bac16423 100644 --- a/addons/medical/CfgVehicles.hpp +++ b/addons/medical/CfgVehicles.hpp @@ -1,7 +1,23 @@ class CfgVehicles { + // Backwards compatibility + // Left as dumb modules so that old missions don't error about missing vehicles class Logic; - // Left as dumb logic so that old missions don't error about missing vehicle - class ACE_moduleMedicalSettings: Logic { - scope = 1; + class Module_F: Logic { + class EventHandlers; }; + class ACE_moduleMedicalSettings: Module_F { + author = ECSTRING(common,ACETeam); + scope = 1; + displayName = "[ACE] Retired Medical module (will have no effect)"; + class EventHandlers: EventHandlers { + init = "diag_log text format ['[ACE] (Medical) Warning retired module [%1] placed (will have no effect)', typeOf (_this select 0)];"; + }; + }; + class ACE_moduleBasicMedicalSettings: ACE_moduleMedicalSettings {}; + class ACE_moduleAdvancedMedicalSettings: ACE_moduleMedicalSettings {}; + class ACE_moduleReviveSettings: ACE_moduleMedicalSettings {}; + class ACE_moduleAssignMedicRoles: ACE_moduleMedicalSettings {}; + class ACE_moduleAssignMedicVehicle: ACE_moduleMedicalSettings {}; + class ACE_moduleAssignMedicalFacility: ACE_moduleMedicalSettings {}; + class ACE_moduleMedicalMenuSettings: ACE_moduleMedicalSettings {}; }; diff --git a/addons/medical/XEH_postInit.sqf b/addons/medical/XEH_postInit.sqf index 5dd19195e8..48d49d678c 100644 --- a/addons/medical/XEH_postInit.sqf +++ b/addons/medical/XEH_postInit.sqf @@ -3,12 +3,13 @@ [QEGVAR(medical,setUnconscious), LINKFUNC(setUnconscious)] call CBA_fnc_addEventHandler; +// For BETA/RC - debug non-default settings to rpt: +call compile preprocessFileLineNumbers QPATHTOF(dev\reportSettings.sqf); + if (!hasInterface) exitWith {}; [missionNamespace, "ACE_setCustomAimCoef", QUOTE(ADDON), { - private _pain = GET_PAIN_PERCEIVED(ACE_player); - - linearConversion [0, 1, _pain, 1, 5, true]; + (linearConversion [0, 1, GET_PAIN_PERCEIVED(ACE_player), 1, 5, true]) + (ACE_player getVariable [QEGVAR(medical_engine,aimFracture), 0]) }] call EFUNC(common,arithmeticSetSource); #ifdef DEBUG_MODE_FULL diff --git a/addons/medical/XEH_preInit.sqf b/addons/medical/XEH_preInit.sqf index aac77adab9..2ebebbbd3d 100644 --- a/addons/medical/XEH_preInit.sqf +++ b/addons/medical/XEH_preInit.sqf @@ -11,7 +11,44 @@ PREP_RECOMPILE_END; // Add warning for old functions that were technically public, Remove at 3.14.0 { missionNamespace setVariable [_x, compileFinal format ['diag_log text "ACE Medical WARNING: Formerly public function [%1] has no effect in medical rewrite."; nil', _x]]; -} forEach ["ace_medical_fnc_actionPlaceInBodyBag","ace_medical_fnc_actionRemoveTourniquet","ace_medical_fnc_addHeartRateAdjustment","ace_medical_fnc_addToLog","ace_medical_fnc_addToTriageCard -","ace_medical_fnc_addUnconsciousCondition","ace_medical_fnc_addVitalLoop","ace_medical_fnc_canAccessMedicalEquipment","ace_medical_fnc_canTreat","ace_medical_fnc_displayTriageCard","ace_medical_fnc_dropDownTriageCard","ace_medical_fnc_getTriageStatus","ace_medical_fnc_getUnconsciousCondition","ace_medical_fnc_hasItem","ace_medical_fnc_hasItems","ace_medical_fnc_hasTourniquetAppliedTo","ace_medical_fnc_isInMedicalFacility","ace_medical_fnc_isInMedicalVehicle","ace_medical_fnc_isMedic","ace_medical_fnc_isMedicalVehicle","ace_medical_fnc_itemCheck","ace_medical_fnc_selectionNameToNumber","ace_medical_fnc_setCardiacArrest","ace_medical_fnc_setDead","ace_medical_fnc_setHitPointDamage","ace_medical_fnc_showBloodEffect","ace_medical_fnc_treatment","ace_medical_fnc_treatmentAdvanced_bandage","ace_medical_fnc_treatmentAdvanced_CPR","ace_medical_fnc_treatmentAdvanced_CPRLocal","ace_medical_fnc_treatmentAdvanced_medication","ace_medical_fnc_treatmentAdvanced_medicationLocal","ace_medical_fnc_treatmentIV","ace_medical_fnc_treatmentIVLocal","ace_medical_fnc_unconsciousPFH","ace_medical_fnc_useItem","ace_medical_fnc_useItems"]; +} forEach [ + QFUNC(actionPlaceInBodyBag), + QFUNC(actionRemoveTourniquet), + QFUNC(addHeartRateAdjustment), + QFUNC(addToLog), + QFUNC(addToTriageCard), + QFUNC(addUnconsciousCondition), + QFUNC(addVitalLoop), + QFUNC(canAccessMedicalEquipment), + QFUNC(canTreat), + QFUNC(displayTriageCard), + QFUNC(dropDownTriageCard), + QFUNC(getTriageStatus), + QFUNC(getUnconsciousCondition), + QFUNC(hasItem), + QFUNC(hasItems), + QFUNC(hasTourniquetAppliedTo), + QFUNC(isInMedicalFacility), + QFUNC(isInMedicalVehicle), + QFUNC(isMedic), + QFUNC(isMedicalVehicle), + QFUNC(itemCheck), + QFUNC(selectionNameToNumber), + QFUNC(setCardiacArrest), + QFUNC(setDead), + QFUNC(setHitPointDamage), + QFUNC(showBloodEffect), + QFUNC(treatment), + QFUNC(treatmentAdvanced_bandage), + QFUNC(treatmentAdvanced_CPR), + QFUNC(treatmentAdvanced_CPRLocal), + QFUNC(treatmentAdvanced_medication), + QFUNC(treatmentAdvanced_medicationLocal), + QFUNC(treatmentIV), + QFUNC(treatmentIVLocal), + QFUNC(unconsciousPFH), + QFUNC(useItem), + QFUNC(useItems) +]; ADDON = true; diff --git a/addons/medical/config.cpp b/addons/medical/config.cpp index e3557fab40..6c93d1e3e8 100644 --- a/addons/medical/config.cpp +++ b/addons/medical/config.cpp @@ -17,3 +17,7 @@ class CfgPatches { #include "ACE_Settings.hpp" #include "CfgEventHandlers.hpp" #include "CfgVehicles.hpp" + +class ACE_Tests { + medicalHitpoints = QPATHTOF(dev\test_hitpointConfigs.sqf); +}; diff --git a/addons/medical/dev/debugDisplay.sqf b/addons/medical/dev/debugDisplay.sqf index 3d8323f46b..541aaaccba 100644 --- a/addons/medical/dev/debugDisplay.sqf +++ b/addons/medical/dev/debugDisplay.sqf @@ -23,7 +23,11 @@ if (!isNull cursorTarget && {cursorTarget isKindOf "CAManBase"}) then { private _targetState = [cursorTarget, EGVAR(medical,STATE_MACHINE)] call CBA_statemachine_fnc_getCurrentState; - drawIcon3D ["", [0.6, 0, 0, 1], cursorTarget modelToWorldVisual (cursorTarget selectionPosition "pelvis"), 0, 0, 0, format ["State: %1", _targetState], 2, 40 * pixelH, "RobotoCondensed"]; + private _targetStateAI = ""; + if (!isNil QEGVAR(medical_ai,stateMachine)) then { + _targetStateAI = [cursorTarget, EGVAR(medical_ai,stateMachine)] call CBA_statemachine_fnc_getCurrentState; + }; + drawIcon3D ["", [0.6, 0, 0, 1], cursorTarget modelToWorldVisual (cursorTarget selectionPosition "pelvis"), 0, 0, 0, format ["State: %1 / %2", _targetState,_targetStateAI], 2, 40 * pixelH, "RobotoCondensed"]; }; }, 0 ,[]] call CBA_fnc_addPerFrameHandler; }, []] call CBA_fnc_waitUntilAndExecute; diff --git a/addons/medical/dev/reportSettings.sqf b/addons/medical/dev/reportSettings.sqf new file mode 100644 index 0000000000..97350121a3 --- /dev/null +++ b/addons/medical/dev/reportSettings.sqf @@ -0,0 +1,14 @@ +#include "\z\ace\addons\medical\script_component.hpp" +// Dumps info on all non-default medical settings + +[{ + private _medicalSettings = cba_settings_allSettings select {(_x select [0,11]) == "ace_medical"}; + INFO_1("-- Checking %1 medical Settings --",count _medicalSettings); + { + private _currentValue = missionNamespace getVariable [_x, "$"]; + private _defaultValue = (cba_settings_default getVariable [_x, []]) param [0, "#"]; + if !(_currentValue isEqualTo _defaultValue) then { + diag_log text format ["%1: [Current %2] [Default: %3]", _x, _currentValue, _defaultValue]; + }; + } forEach _medicalSettings; +}, nil, 2] call CBA_fnc_waitAndExecute; diff --git a/addons/medical/dev/test_hitpointConfigs.sqf b/addons/medical/dev/test_hitpointConfigs.sqf new file mode 100644 index 0000000000..8838b1d744 --- /dev/null +++ b/addons/medical/dev/test_hitpointConfigs.sqf @@ -0,0 +1,33 @@ +// PabstMirror +// ["medicalHitpoints"] call ace_common_fnc_runTests; +// execVM "\z\ace\addons\medical\dev\test_hitpointConfigs.sqf" + +#include "\z\ace\addons\medical\script_component.hpp" + +// UAV-AI should get filtered by scope check +private _mans = configProperties [configFile >> "CfgVehicles", "(isClass _x) && {(getNumber (_x >> 'scope')) == 2} && {configName _x isKindOf 'CAManBase'}", true]; +INFO_1("Checking mans for medical hitpoints [%1 mans]",count _mans); + +private _testPass = true; +{ + private _typeOf = configName _x; + private _hitpoints = (configProperties [_x >> "HitPoints", "isClass _x", true]) apply {configName _x}; + + // _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 == "HitLeftArm"}) == -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 _mans; + +_testPass diff --git a/addons/medical/dev/watchVariable.sqf b/addons/medical/dev/watchVariable.sqf index 0e39cae4cd..0d02a74e19 100644 --- a/addons/medical/dev/watchVariable.sqf +++ b/addons/medical/dev/watchVariable.sqf @@ -1,9 +1,13 @@ #include "\z\ace\addons\medical\script_component.hpp" +if (missionNamespace getVariable [QGVAR(dev_watchVariableRunning), false]) exitWith {}; +GVAR(dev_watchVariableRunning) = true; + ["medical", { // Hide when patient display is up because they might overlap - if (!isNull EGVAR(medical_gui,displayPatientInformationTarget)) exitWith {""}; + private _display = uiNamespace getVariable [QEGVAR(medical_gui,RscPatientInfo), displayNull]; + if (!isNull _display) exitWith {"Paused"}; private _unit = cursorTarget; if (!(_unit isKindOf "CAManBase")) then {_unit = cursorObject}; @@ -18,12 +22,16 @@ _return pushBack ""; // State: - private _hasStableVitals = [_unit] call EFUNC(medical_status,hasStableVitals); private _targetState = [_unit, EGVAR(medical,STATE_MACHINE)] call CBA_statemachine_fnc_getCurrentState; if (!local _unit) then {_targetState = "NotLocal";}; private _color = switch (_targetState) do {case "Default": {"33FF33"}; case "Injured": {"FF3333"}; case "Unconscious": {"FF8833"}; case "CardiacArrest": {"FF33AA"}; default {"555555"}}; - private _unconcFlag = if IS_UNCONSCIOUS(_unit) then {"[U]"} else {""}; - _return pushBack format ["State: %2 [StableVitals: %3] %4", _color, _targetState, _hasStableVitals, _unconcFlag]; + _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 _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]; // Blood: private _bloodVolume = GET_BLOOD_VOLUME(_unit); @@ -40,7 +48,7 @@ private _heartRate = GET_HEART_RATE(_unit); GET_BLOOD_PRESSURE(_unit) params ["_bpLow", "_bpHigh"]; _return pushBack format ["CardiacOutput %1", _cardiacOutput toFixed 5]; - _return pushBack format [" - [HR: %1] [BP: %2 / %3]", _heartRate toFixed 1, _bpLow toFixed 1, _bpHigh toFixed 1]; + _return pushBack format [" - [HR: %1] [BP: %2 / %3]", _heartRate toFixed 1, _bpHigh toFixed 1, _bpLow toFixed 1]; // Pain: private _pain = GET_PAIN(_unit); @@ -53,12 +61,16 @@ // 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 {""}; - _return pushBack format ["Damage: [H: %1] [B: %2] %3", (_damage select 0) toFixed 2, (_damage select 1) toFixed 2]; + _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]; _return pushBack format ["Hitpoints: [HHed:%1] [HBod: %2]", (_unit getHitPointDamage "HitHead") toFixed 2, (_unit getHitPointDamage "HitBody") toFixed 2]; _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]"}; + _return pushBack format ["Fractures: %1 %2", _fractures, _canSprint]; + // Tourniquets: _return pushBack "------- Tourniquets: -------"; @@ -70,7 +82,7 @@ _return pushBack format ["%1 [Time On: %2]", ALL_SELECTIONS select _tPartNum, (CBA_missionTime - _x) toFixed 1]; }; { - _x params ["", "_medClassname", "_medPartNum"]; + _x params ["_medPartNum", "_medClassname"]; if (_medPartNum == _tPartNum) then { _return pushBack format [" - Occluded Med: %1", _medClassname]; }; @@ -79,27 +91,27 @@ // Wounds: - _return pushBack "------- Wounds: -------"; - private _wounds = _unit getVariable [QEGVAR(medical,openWounds), []]; + _return pushBack "------- Open Wounds: -------"; + private _wounds = GET_OPEN_WOUNDS(_unit); { - _x params ["", "_xClassID", "_xBodyPartN", "_xAmountOf", "_xBleeding", "_xDamage", "_xCategory"]; - _return pushBack format ["%1: [%2-%3] [x%4] [Bld: %5] [Dmg: %6]", ALL_SELECTIONS select _xBodyPartN, _xClassID, _xCategory, _xAmountOf toFixed 1, _xBleeding toFixed 4, _xDamage toFixed 2]; + _x params ["_xClassID", "_xBodyPartN", "_xAmountOf", "_xBleeding", "_xDamage"]; + _return pushBack format ["%1: [%2] [x%3] [Bld: %4] [Dmg: %5]", ALL_SELECTIONS select _xBodyPartN, _xClassID, _xAmountOf toFixed 1, _xBleeding toFixed 4, _xDamage toFixed 2]; } forEach _wounds; // Bandaged Wounds: _return pushBack "------- Bandaged Wounds: -------"; - private _wounds = _unit getVariable [QEGVAR(medical,bandagedWounds), []]; + private _wounds = GET_BANDAGED_WOUNDS(_unit); { - _x params ["", "_xClassID", "_xBodyPartN", "_xAmountOf", "_xBleeding", "_xDamage", "_xCategory"]; - _return pushBack format ["%1: [%2-%3] [x%4] [Bld: %5] [Dmg: %6]", ALL_SELECTIONS select _xBodyPartN, _xClassID, _xCategory, _xAmountOf toFixed 1, _xBleeding toFixed 4, _xDamage toFixed 2]; + _x params ["_xClassID", "_xBodyPartN", "_xAmountOf", "_xBleeding", "_xDamage"]; + _return pushBack format ["%1: [%2] [x%3] [Bld: %4] [Dmg: %5]", ALL_SELECTIONS select _xBodyPartN, _xClassID, _xAmountOf toFixed 1, _xBleeding toFixed 4, _xDamage toFixed 2]; } forEach _wounds; // Stitched Wounds: _return pushBack "------- Stitched Wounds: -------"; - private _wounds = _unit getVariable [QEGVAR(medical,stitchedWounds), []]; + private _wounds = GET_STITCHED_WOUNDS(_unit); { - _x params ["", "_xClassID", "_xBodyPartN", "_xAmountOf", "_xBleeding", "_xDamage", "_xCategory"]; - _return pushBack format ["%1: [%2-%3] [x%4] [Bld: %5] [Dmg: %6]", ALL_SELECTIONS select _xBodyPartN, _xClassID, _xCategory, _xAmountOf toFixed 1, _xBleeding toFixed 4, _xDamage toFixed 2]; + _x params ["_xClassID", "_xBodyPartN", "_xAmountOf", "_xBleeding", "_xDamage"]; + _return pushBack format ["%1: [%2] [x%3] [Bld: %4] [Dmg: %5]", ALL_SELECTIONS select _xBodyPartN, _xClassID, _xAmountOf toFixed 1, _xBleeding toFixed 4, _xDamage toFixed 2]; } forEach _wounds; // IVs: @@ -115,17 +127,11 @@ private _hrTargetAdjustment = 0; private _painSupressAdjustment = 0; private _peripheralResistanceAdjustment = 0; - private _medicationCounts = []; + private _uniqueMedications = []; private _rawMedications = (_unit getVariable [VAR_MEDICATIONS, []]) apply { _x params ["_medication", "_timeAdded", "_timeTillMaxEffect", "_maxTimeInSystem", "_hrAdjust", "_painAdjust", "_flowAdjust"]; + _uniqueMedications pushBackUnique _medication; private _timeInSystem = CBA_missionTime - _timeAdded; - private _index = _medicationCounts find _medication; - if (_index < 0) then { - _index = _medicationCounts pushBack _medication; - _medicationCounts pushBack 0 - }; - _medicationCounts set [(_index + 1), (_medicationCounts select (_index + 1)) + linearConversion [_timeTillMaxEffect, _maxTimeInSystem, _timeInSystem, 1, 0, true]]; - private _effectRatio = (((_timeInSystem / _timeTillMaxEffect) ^ 2) min 1) * (_maxTimeInSystem - _timeInSystem) / _maxTimeInSystem; _hrTargetAdjustment = _hrTargetAdjustment + _hrAdjust * _effectRatio; _painSupressAdjustment = _painSupressAdjustment + _painAdjust * _effectRatio; @@ -133,16 +139,23 @@ format ["%1 [%2 / %3][%4][%5,%6,%7]",_medication,_timeInSystem toFixed 0,_maxTimeInSystem toFixed 0, _effectRatio toFixed 2, _hrAdjust toFixed 1, _painAdjust toFixed 2, _flowAdjust toFixed 1]; }; _return pushBack format ["Adjusts: [HR %1][PS %2][PR %3]", _hrTargetAdjustment toFixed 2, _painSupressAdjustment toFixed 2, _peripheralResistanceAdjustment toFixed 2]; - for "_i" from 0 to (count _medicationCounts) - 1 step 2 do { - _return pushBack format ["-%1: %2", _medicationCounts select _i, _medicationCounts select _i + 1]; - }; + { + private _medicationCount = [_unit, _x, true] call EFUNC(medical_status,getMedicationCount); + private _medicationEffectiveness = [_unit, _x, false] call EFUNC(medical_status,getMedicationCount); + _return pushBack format ["-%1: C: %2 - E: %3", _x, _medicationCount toFixed 2, _medicationEffectiveness toFixed 2]; + } forEach _uniqueMedications; _return pushBack "------- Medications Raw: -------"; _return append _rawMedications; + if (_unit isEqualTo ACE_player) then { + _return pushBack format ["ACE_setCustomAimCoef: %1", [missionNamespace, "ACE_setCustomAimCoef", "max"] call EFUNC(common,arithmeticGetResult)]; + }; + + _return pushBack format ["%1 - %2",lifeState _unit, animationState _unit]; + // Footer: _return pushBack ""; // Return: _return joinString "
" }, [40]] call EFUNC(common,watchVariable); - diff --git a/addons/medical/functions/fnc_addDamageToUnit.sqf b/addons/medical/functions/fnc_addDamageToUnit.sqf index cde34b31d6..4e2561438e 100644 --- a/addons/medical/functions/fnc_addDamageToUnit.sqf +++ b/addons/medical/functions/fnc_addDamageToUnit.sqf @@ -25,10 +25,12 @@ params [["_unit", objNull, [objNull]], ["_damageToAdd", -1, [0]], ["_bodyPart", "", [""]], ["_typeOfDamage", "", [""]], ["_instigator", objNull, [objNull]]]; TRACE_5("addDamageToUnit",_unit,_damageToAdd,_bodyPart,_typeOfDamage,_instigator); -private _bodyPartIndex = ALL_BODY_PARTS find (toLower _bodyPart); -if (isNull _unit || {!local _unit} || {!alive _unit}) exitWith {ERROR_1("addDamageToUnit - badUnit %1", _this); false}; -if (_damageToAdd < 0) exitWith {ERROR_1("addDamageToUnit - bad damage %1", _this); false}; +_bodyPart = toLower _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}; // Extension is case sensitive and expects this format (different from ALL_BODY_PARTS) _bodyPart = ["Head", "Body", "LeftArm", "RightArm", "LeftLeg", "RightLeg"] select _bodyPartIndex; diff --git a/addons/medical/functions/fnc_adjustPainLevel.sqf b/addons/medical/functions/fnc_adjustPainLevel.sqf index 40370bf99d..233638180f 100644 --- a/addons/medical/functions/fnc_adjustPainLevel.sqf +++ b/addons/medical/functions/fnc_adjustPainLevel.sqf @@ -2,6 +2,7 @@ /* * Author: PabstMirror * Public interface to allow external modules to safely adjust pain levels. + * Added pain can be positive or negative (Note: ignores painCoefficient setting) * * Arguments: * 0: The patient diff --git a/addons/medical/functions/fnc_setUnconscious.sqf b/addons/medical/functions/fnc_setUnconscious.sqf index 618432a5fc..f6f39b03c5 100644 --- a/addons/medical/functions/fnc_setUnconscious.sqf +++ b/addons/medical/functions/fnc_setUnconscious.sqf @@ -2,7 +2,6 @@ /* * Author: Glowbal * Sets a unit in the unconscious state. - * For Public Use * * Arguments: * 0: The unit that will be put in an unconscious state @@ -17,7 +16,7 @@ * [bob, true] call ace_medical_fnc_setUnconscious; * [player, true, 5, true] call ace_medical_fnc_setUnconscious; * - * Public: yes + * Public: Yes */ // only run this after the settings are initialized @@ -62,6 +61,7 @@ if (_knockOut) then { }, [_unit], _minWaitingTime] call CBA_fnc_waitAndExecute; }; if (EGVAR(medical,spontaneousWakeUpChance) > 0) then { + TRACE_1("setting lastWakeUpCheck",_minWaitingTime); _unit setVariable [QEGVAR(medical,lastWakeUpCheck), CBA_missionTime + _minWaitingTime - SPONTANEOUS_WAKE_UP_INTERVAL]; }; }; diff --git a/addons/medical/initSettings.sqf b/addons/medical/initSettings.sqf index 0ae2c0e9f1..6eaed9623a 100644 --- a/addons/medical/initSettings.sqf +++ b/addons/medical/initSettings.sqf @@ -1,14 +1,39 @@ -// CBA Settings [ADDON: ace_medical]: - -private _categoryArray = [LELSTRING(medical,Category_DisplayName), "?"]; - -// todo: Check the description is still accurate [ - QGVAR(spontaneousWakeUpChance), "SLIDER", - [LSTRING(MedicalSettings_spontaneousWakeUpChance_DisplayName), LSTRING(MedicalSettings_spontaneousWakeUpChance_Description)], - _categoryArray, - [0,1,0.05,2], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(spontaneousWakeUpChance), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(limping), + "LIST", + [LSTRING(Limping_DisplayName), LSTRING(Limping_Description)], + LSTRING(Category), + [[0, 1, 2], [ELSTRING(common,Disabled), LSTRING(Limping_LimpOnOpenWounds), LSTRING(Limping_LimpRequiresStitching)], 1], + true, + {[QGVAR(limping), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true +] call CBA_settings_fnc_init; + +[ + QGVAR(fractures), + "LIST", + [LSTRING(Fractures_DisplayName), LSTRING(Fractures_Description)], + LSTRING(Category), + [[0, 1, 2], [ELSTRING(common,Disabled), LSTRING(Fractures_SplintHealsFully), LSTRING(Fractures_SplintHasEffects)], 1], + true, + {[QGVAR(fractures), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true +] call CBA_settings_fnc_init; + +[ + QGVAR(spontaneousWakeUpChance), + "SLIDER", + [LSTRING(SpontaneousWakeUpChance_DisplayName), LSTRING(SpontaneousWakeUpChance_Description)], + LSTRING(Category), + [0, 1, 0.05, 2], + true +] call CBA_settings_fnc_init; + +[ + QGVAR(spontaneousWakeUpEpinephrineBoost), + "SLIDER", + [LSTRING(spontaneousWakeUpEpinephrineBoost_DisplayName), LSTRING(spontaneousWakeUpEpinephrineBoost_Description)], + LSTRING(Category), + [1, 30, 1, 1], + true ] call CBA_settings_fnc_init; diff --git a/addons/medical/stringtable.xml b/addons/medical/stringtable.xml index 081e000d92..762188b924 100644 --- a/addons/medical/stringtable.xml +++ b/addons/medical/stringtable.xml @@ -1,7 +1,7 @@ - + ACE Medical ACE: медицина ACE Opcje medyczne @@ -17,117 +17,75 @@ ACE 医疗系统 ACE 醫療系統 - - Medical Level - Сложность медицины - Poziom medyczny - Nivel médico - Stufe des Sanitätssystem - Úroveň medického - Nível médico - Niveau de simulation médicale - Orvosi szint - Livello Medico - 医療レベル - 의료 수준 - 医疗等级 - 醫療等級 + + Unconscious Wake Up Chance + Wahrscheinlichkeit aufzuwachen + 気絶から覚醒する可能性 + Шанс очнуться при потере сознания + Chance de reprendre connaissance + Chance de recuperar consciência - - What is the medical simulation level? - Каков уровень сложности медицинской системы? - Jaki jest poziom symulacji medycznej? - ¿Cuál es el nivel de simulación médica? - Wie hoch soll das medizinische Simulationslevel sein? - Jaká je úroveň lékařské simulace? - Qual o nível de simulação médica? - Quel niveau de simulation médicale choisissez-vous? - Milyen komplex legyen az orvosi szimuláció? - Qual'è il livello di simulazione medica? - 治療の再現度は? - 의료 시뮬레이션의 수준 - 选择需要的医疗模拟等级 - 選擇需要的醫療模擬等級 + + The probablity that a unit 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 сек) + La probabilité pour qu'une unité en état stable puisse reprendre conscience (état vérifié toutes les 15 secondes). + A probabilidade que uma unidade com vitais estabilizados possa recuperar consciências (verificado a cada 15 segundos) - - Disable medics - Отключить медиков - Wyłącz medyków - Desactivar médicos - Sanitäter deaktivieren - Zakázat zdravotníky - Desativar médicos - Désactiver les infirmiers - Orvosok letiltása - Disabilita medici - 衛生兵を無効化 - 의무병 비활성화 - 关闭医护兵 - 關閉醫護兵 + + Epinephrine Increases Wake Up Chance - - Enable Litter - Включить мусор - Aktywuj odpadki - Activar restos médicos - Abfälle aktivieren - Povolit odpadky - Ativar lixo médico - Activer les détritus - Szemét engedélyezése - Abilita Barella - 医療廃棄物の表示を有効化 - 의료폐기물 활성화 - 启用医疗废弃物 - 啟用醫療廢棄物 + + Increases how often spontaneous wake up checks happen when patient has Epinephrine in their system. - - Enable litter being created upon treatment - Включить появление мусора после лечения - Twórz odpadki medyczne podczas leczenia - Activar los restos médicos que se crean en el tratamiento - Aktiviere Abfälle, wenn eine Behandlung durchgeführt wurde - Vytváří odpad zdravotnického materiálu pří léčení - Ativar lixo ser criado após tratamento - Activer la création de détrimus au début des traitements - Engedélyezi a szemét keletkezését ellátáskor - Abilita la creazione della barella dopo trattamento - 治療を始めると、医療廃棄物の作成を有効化する - 의료폐기물이 치료중 주변에 생성되는것을 활성화 합니다 - 本功能启用后,当每次医疗动作结束时,地上会产生相应的医疗废弃物 - 本功能啟用後,當每次醫療動作結束時,地上會產生相應的醫療廢棄物 + + Limping + Хромота + 跛行 + Boitement + Mancando - - Life time of litter objects - Время удаления мусора - Długość życia odpadków - Tiempo de vida de los restos médicos - Dauer des angezeigten Abfalls - Životnost pro odpadky - Tempo de vida dos objetos do lixo - Durée d'affichage des détritus - Szemétobjektumok élettartama - Tempo di vita delle barelle - 医療廃棄物の作成限界数を設定 - 의료폐기물 시간제한 - 医疗废弃物存在时间 - 醫療廢棄物存在時間 + + Controls whether open or bandaged wounds cause a person to limp. - - How long should litter objects stay? In seconds. -1 is forever. - Как долго мусор будет оставаться на земле? В секундах. -1 означает бесконечное время. - Ile czasu musi upłynąć, aby odpadki zaczęły znikać? W sekundach. -1 dla nieskończoności. - ¿Por cuánto tiempo deben permanecer los restos médicos? En segundos. -1 es para siempre. - Wie lange sollen Abfälle am Boden liegen (in Sekunden)? -1 ist für immer. - Za jak dlouho začnou odpadky mizet? V sekundách. -1 navždy. - Quanto tempo os objetos do lixo devem ficar? Em segundos. -1 é para sempre. - Combien de temps doivent rester affiché les détritus? En secondes. -1 pour tout le temps - Milyen sokáig legyenek jelen a szemétobjektumok (másodpercben)? A -1 végtelen időt jelent. - Per quanto devono restare le barelle? In secondi. -1 è permanente - 医療廃棄物オブジェクトが表示されつづける時間を設定しますか? -1 は永遠です。 - 얼마동안 폐기물이 존재합니까? 초 단위. -1 은 영구적. - 定义医疗废弃物存在时间,以秒为单位,-1为永远存在。 - 定義醫療廢棄物存在時間,以秒為單位,-1為永遠存在。 + + Limp on Open Wounds + Хромота при открытых ранах + 創傷開放時に跛行 + Boiter si plaies ouvertes + Mancar se possuir feridas abertas + + + Limp on Open or Bandaged Wounds + Хромота при открытых или забинтованых ранах + 負傷時は引きずって歩くようにします + Boiter si plaies ouvertes ou pansées + Mancar se possuir feridas abertas ou atadas + + + Fractures + Переломы + 骨折 + Fractures + Fraturas + + + Controls the effect of using splints to treat fractures.\nWhen disabled, injuries will not cause fractures. + + + Splints Fully Heal Fractures + Шины полностью лечат перелом + 添え木で骨折完治 + Les attelles guérissent complètement les fractures + Tala cura fraturas completamente + + + Splints Heal, but Cannot Sprint + Шины вылечивают, но не дают бегать + 添え木で治療しますが、走れません + Les attelles guérissent les fractures, mais empêchent de courir + Talas curam (mas não consegue correr) Remote Controlled AI @@ -136,7 +94,7 @@ IA controlada remotamente Zdalnie sterowane AI Vzdáleně ovládané AI - Contrôle à distance des IA + IA contrôlées à distance Távvezérelt AI Зевса считать ботом IA Controllate in Remoto @@ -152,7 +110,7 @@ Tratar unidades remotamente controladas como IA? Traktuj jednostki zdalnie sterowane (przez Zeusa) jako AI, nie jako graczy? Ošetřit vzdáleně ovládané jednotky jako AI, ne jako hráče? - Soigner les unitées controlées à distance comme des IA et non comme des joueurs? + Définit si les unités contrôlées à distance sont traitées comme des IA, et non comme des joueurs. Távvezérelt egységek AI-ként, nem játékosként való kezelése? Обрабатывать дистанционно управляемых юнитов как ботов, а не как игроков? Considera le unità controllate in remoto come IA e non come giocatori? @@ -185,7 +143,7 @@ Lässt eine Einheit bewusstlos werden anstatt zu sterben Jednotka upadne do bezvědomí namísto smrti Fazer a unidade ficar inconsciente invés de morrer - Forcer l'inconscience au lieu de la mort instantanée + Force une unité à perdre connaissance, au lieu de mourir sur le coup. Egy egység kerüljön eszméletlen állapotba a halott helyett Imposta un'unità come incosciente invece di morta ユニットの即死を防止するために、気絶へ移行させます @@ -201,7 +159,7 @@ Aktiviert ein Sanitätssystem für Spieler und KI. Poskytuje zdravotní systém pro hráče a AI. Proporciona o sistema médico para os jogadores e a IA. - Fourni un système médical pour les joueurs et les IA. + Fournit un système médical à la fois pour les joueurs, et pour les IA. Egy orvosi rendszert ad játékosok és AI-k számára. Fornisce un sistema medico sia per giocatori che IA. プレイヤーと AI の両方へ医療システムを提供します。 @@ -209,21 +167,6 @@ 医疗系统将同时对玩家与AI发生作用 醫療系統將同時對玩家與AI發生作用 - - Basic Medical Settings [ACE] - Standard Sanitätseinstellungen [ACE] - Podstawowe ustawienia medyczne - Ajustes médicos básicos [ACE] - Paramètres des soins basiques [ACE] - Impostazioni Mediche Di Base [ACE] - Základní zdravotnické nastavení [ACE] - Ajustes médicos básicos [ACE] - Настройки базовой медицины [ACE] - ベーシック医療設定 [ACE] - 기본 의료 설정 [ACE] - 基本医疗设定 [ACE] - 基本醫療設定 [ACE] - Enabled for Включено для @@ -248,7 +191,7 @@ Wähle aus, welche Einheiten unter das erweiterte Sanitätssystem fallen Vyberte, pro jaké jednotky bude pokročilý zdravotní systém povolen Selecione quais unidades o sistema médico avançado será habilitado - Sélectionne pour quelles unités les soins avancés seront activés + 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 i sistema medico avanzato 選択されたユニットが、アドバンスド医療が使えるようになります @@ -264,7 +207,7 @@ Nur Spieler Pouze hráči Somente jogadores - Joueur uniquement + Joueurs uniquement Csak játékosok Solo giocatori プレイヤーのみ @@ -296,7 +239,7 @@ Fahrzeugunfälle Poškození z kolize Batidas de veículos - Accident en véhicule + Accidents en véhicule Járműbalesetek Schianto Veicoli 車両の衝突 @@ -312,7 +255,7 @@ Verursacht ein Fahrzeugunfall Verletzungen Dostane jednotka poškození při autonehodě? As unidades recebem dano de uma batida de veículo? - Les unités subissent des dégats lors d'accident + Définit si les unités subissent des dégâts en cas d'accidents en véhicule. Sérülnek-e az egységek autós ütközés során? Le unità sostengono danni da incidenti con veicoli? ユニットは車両の衝突による損傷を受けるようにしますか? @@ -320,21 +263,6 @@ 设定人员是否会因为载具冲撞别的物件而产生伤害? 設定人員是否會因為載具衝撞別的物件而產生傷害? - - Where can the Epinephrine be used? (Basic Medical) - Wo kann Epiniphrin verwendet werden? (Standard Sanitätseinstellungen) - Configura donde puede usarse Epinefrina (Solo sistema médico básico) - Gdzie można korzystać z adrenaliny? (Podstawowy system medyczny) - Où peut être utilisé l'épinéphrine ? (Médical basique) - Dove si può usare l'epinefrina? (Sistema medico di base) - Kde může být použit adrenalin? (Pouze základní zdravotní systém) - Onde pode-se usar a Epinefrina? (Somente sistema médico básico) - Где может использоваться адреналин? (Базовая медицина) - どこでもアドレナリンを使えるようにしますか? (ベーシック医療のみ) - 어디에서 에피네프린을 사용할 수 있습니까? (기본 의료) - 在哪里可以使用肾上腺素? (基本医疗) - 在哪裡可以使用腎上腺素? (基本醫療) - Heal hitpoints Heile Trefferpunkte @@ -344,7 +272,7 @@ Curar hitpoints Léčit hitponty Cura Hitpoints - Soigner les blessures + Guérir les blessures ヒットポイントの回復 체력 회복 完整治疗 @@ -359,7 +287,7 @@ Curar totalmente hitpoints enfaixados Heal fully bandaged hitpoints Cura Hitpoints completamente bendati - Soigner les plaies entièrement bandées. + Les plaies entièrement bandées seront guéries. 包帯によりヒットポイントを完全に回復する 붕대를 감아서 체력을 회복 @@ -368,7 +296,7 @@ Behandlungseinstellungen der Standard ACE-Medizin konfigurieren Configure las opciones de tratamiento del sistema médico básico de ACE Skonfiguruj ustawienia leczenia podstawowego systemu medycznego ACE - Configure les réglages de traitement dans ACE médical basique + Configurer les paramètres de traitement à partir de 'ACE médical basique'. Configura le impostazioni trattamenti per ACE Medical di base Configura as opções de tratamento do sistema médico básico do ACE Настройка лечения в базовой медицинской системе ACE @@ -440,46 +368,31 @@ 设定当距离超过%1将不能使用治疗动作 設定當距離超過%1將不能使用治療動作 - - This person (%1) is awake and cannot be loaded - Diese Person (%1) ist wach und kann nicht verladen werden - Ta osoba (%1) jest przytomna i nie może zostać załadowana - Esta persona (%1) está despierto y no puede ser cargado - Боец (%1) в сознании и не может быть погружен - Esta pessoa (%1) está acordada e não pode ser carregada - Tato osoba (%1) je vzhůru a nemůže být naložena - Questa persona (%1) è sveglia e non può essere caricata. - %1 est conscient et ne peut être embarqué. - 患者 (%1) は意識があり、積み込めない - 이 사람 (%1) 은(는) 의식이 있어 태우지 못합니다 - 此人(%1)是清醒且不能被装载 - 此人(%1)是清醒且不能被裝載 - - - Unconscious Wake Up Chance - - - Probablity that a unit with stable vitals will wake up from unconscious [Checked every 15 sec] - Open lid Deckel aufklappen - フタをあける + フタを開ける Apri lid 打開蓋子 打开盖子 뚜껑 열기 Otwórz pokrywę + Открыть крышку + Ouvrir le couvercle + Abrir Tampa Close lid Deckel zuklappen - フタをしめる + フタを閉める Chiudi lid 關閉蓋子 关闭盖子 뚜껑 닫기 Zamknij pokrywę + Закрыть крышку + Fermer le couvercle + Fechar Tampa diff --git a/addons/medical_ai/StateMachine.hpp b/addons/medical_ai/StateMachine.hpp deleted file mode 100644 index 0c428e4c65..0000000000 --- a/addons/medical_ai/StateMachine.hpp +++ /dev/null @@ -1,86 +0,0 @@ -class GVAR(stateMachine) { - list = QUOTE(call EFUNC(common,getLocalUnits)); - skipNull = 1; - - class Initial { - class Injured { - targetState = "Injured"; - condition = QFUNC(isInjured); - }; - class HealUnit { - targetState = "HealUnit"; - condition = QUOTE((call FUNC(isSafe)) && {call FUNC(wasRequested)}); - }; - }; - - class Injured { - #ifdef DEBUG_MODE_FULL - onState = "systemChat format [""%1 is injured"", _this]"; - #endif - - class InSafety { - targetState = "Safe"; - condition = QFUNC(isSafe); - }; - }; - - class Safe { - #ifdef DEBUG_MODE_FULL - onState = "systemChat format [""%1 is injured, but safe"", _this]"; - #endif - - class RequestMedic { - targetState = "HealSelf"; - condition = QFUNC(canRequestMedic); - onTransition = QFUNC(requestMedic); - }; - class HealSelf { - targetState = "HealSelf"; - condition = "true"; - }; - }; - - class HealSelf { - onState = QFUNC(healSelf); - onStateLeaving = QUOTE(_this setVariable [ARR_2(QUOTE(QGVAR(treatmentOverAt)),nil)]); - - class Initial { - // Go back to initial state when done healing - targetState = "Initial"; - condition = QUOTE( \ - !(call FUNC(isInjured)) \ - && {_this getVariable [ARR_2(QUOTE(QGVAR(treatmentOverAt)),CBA_missionTime)] <= CBA_missionTime} \ - ); - }; - class Injured { - // Stop treating when it's no more safe - targetState = "Injured"; - condition = QUOTE( \ - !(call FUNC(isSafe)) \ - && {_this getVariable [ARR_2(QUOTE(QGVAR(treatmentOverAt)),CBA_missionTime)] <= CBA_missionTime} \ - ); - }; - }; - - class HealUnit { - onState = QFUNC(healUnit); - onStateLeaving = QUOTE(_this setVariable [ARR_2(QUOTE(QGVAR(treatmentOverAt)),nil)]); - - class Initial { - // Go back to initial state when done healing or it's no more safe to treat - targetState = "Initial"; - condition = QUOTE( \ - !((call FUNC(wasRequested)) && {call FUNC(isSafe)}) \ - && {_this getVariable [ARR_2(QUOTE(QGVAR(treatmentOverAt)),CBA_missionTime)] <= CBA_missionTime} \ - ); - }; - class Injured { - // Treating yourself has priority - targetState = "Injured"; - condition = QUOTE( \ - (call FUNC(isInjured)) \ - && {_this getVariable [ARR_2(QUOTE(QGVAR(treatmentOverAt)),CBA_missionTime)] <= CBA_missionTime} \ - ); - }; - }; -}; diff --git a/addons/medical_ai/XEH_PREP.hpp b/addons/medical_ai/XEH_PREP.hpp index f55636612a..9300f0cbb3 100644 --- a/addons/medical_ai/XEH_PREP.hpp +++ b/addons/medical_ai/XEH_PREP.hpp @@ -1,4 +1,5 @@ PREP(canRequestMedic); +PREP(healingLogic); PREP(healSelf); PREP(healUnit); PREP(isInjured); diff --git a/addons/medical_ai/XEH_postInit.sqf b/addons/medical_ai/XEH_postInit.sqf index e3a902d27a..d8676e9695 100644 --- a/addons/medical_ai/XEH_postInit.sqf +++ b/addons/medical_ai/XEH_postInit.sqf @@ -1,35 +1,14 @@ #include "script_component.hpp" -/*["ace_settingsInitialized", { +["ace_settingsInitialized", { 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 - // Only run for AI that does not have to deal with advanced medical - if (EGVAR(medical,enableFor) == 1 || {hasInterface}) exitWith {}; - ["ace_firedNonPlayer", { _unit setVariable [QGVAR(lastFired), CBA_missionTime]; }] call CBA_fnc_addEventHandler; - if (hasInterface) then { - ["ace_unconscious", { - params ["_unit", "_unconscious"]; - if (!_unconscious || {_unit != ACE_player}) exitWith {}; + #include "stateMachine.sqf" +}] call CBA_fnc_addEventHandler; - private _medic = objNull; - { - if ((!isPlayer _x) && {[_x] call EFUNC(medical_treatment,isMedic)}) exitWith { - _medic = _x; - }; - } forEach (units _unit); - if (isNull _medic) exitWith {}; - - private _healQueue = _medic getVariable [QGVAR(healQueue), []]; - _healQueue pushBack _unit; - _medic setVariable [QGVAR(healQueue), _healQueue]; - }] call CBA_fnc_addEventHandler; - }; - - GVAR(statemachine) = [configFile >> "ACE_Medical_AI_StateMachine"] call CBA_statemachine_fnc_createFromConfig; -}] call CBA_fnc_addEventHandler;*/ diff --git a/addons/medical_ai/config.cpp b/addons/medical_ai/config.cpp index e9df7730c4..c42fc98f95 100644 --- a/addons/medical_ai/config.cpp +++ b/addons/medical_ai/config.cpp @@ -16,4 +16,3 @@ class CfgPatches { #include "ACE_Settings.hpp" #include "CfgEventHandlers.hpp" -#include "StateMachine.hpp" diff --git a/addons/medical_ai/functions/fnc_canRequestMedic.sqf b/addons/medical_ai/functions/fnc_canRequestMedic.sqf index 8865819d6a..c2a29c1c9f 100644 --- a/addons/medical_ai/functions/fnc_canRequestMedic.sqf +++ b/addons/medical_ai/functions/fnc_canRequestMedic.sqf @@ -10,7 +10,7 @@ * Can request medic * * Example: - * call ACE_medical_ai_fnc_canRequestMedic + * player call ACE_medical_ai_fnc_canRequestMedic * * Public: No */ @@ -21,10 +21,14 @@ if ([_this] call EFUNC(medical_treatment,isMedic) || {vehicle _this != _this}) exitWith {false}; +// Search for a medic, prioritize unitReady +private _medic = objNull; { - if ([_x] call EFUNC(medical_treatment,isMedic) && {!([_x] call EFUNC(common,isPlayer))}) exitWith { - _this setVariable [QGVAR(assignedMedic), _x]; - true - }; - false + if ([_x] call EFUNC(medical_treatment,isMedic) && {!([_x] call EFUNC(common,isPlayer))} && { + _medic = _x; + (unitReady _medic) + }) exitWith {}; } forEach (units _this); + +_this setVariable [QGVAR(assignedMedic), _medic]; +!isNull _medic diff --git a/addons/medical_ai/functions/fnc_healSelf.sqf b/addons/medical_ai/functions/fnc_healSelf.sqf index c03dccdad8..524625f3c3 100644 --- a/addons/medical_ai/functions/fnc_healSelf.sqf +++ b/addons/medical_ai/functions/fnc_healSelf.sqf @@ -18,41 +18,8 @@ // Player will have to do this manually of course if ([_this] call EFUNC(common,isPlayer)) exitWith {}; // Can't heal self when unconscious -if IS_UNCONSCIOUS(_this) exitWith {}; -// Check if we're still treating -if ((_this getVariable [QGVAR(treatmentOverAt), CBA_missionTime]) > CBA_missionTime) exitWith {}; - -private _needsBandaging = GET_BLOOD_LOSS(_this) > 0; -private _needsMorphine = GET_PAIN(_this) > 0.2; - -switch (true) do { - case _needsBandaging: { - // Select first wound and bandage it - private _openWounds = _this getVariable [QEGVAR(medical,openWounds), []]; - private _partIndex = { - _x params ["", "", "_index", "_amount", "_percentage"]; - if (_amount * _percentage > 0) exitWith { - _index - }; - } forEach _openWounds; - private _selection = ALL_BODY_PARTS select _partIndex; - [_this, "BasicBandage", _selection] call EFUNC(medical_treatment,treatmentBandageLocal); - - #ifdef DEBUG_MODE_FULL - systemChat format ["%1 is bandaging selection %2", _this, _selection]; - #endif - - // Play animation - [_this, true, true] call FUNC(playTreatmentAnim); - _this setVariable [QGVAR(treatmentOverAt), CBA_missionTime + 5]; - }; - case _needsMorphine: { - [_this, "Morphine", 2] call EFUNC(medical_treatment,treatmentMedicationLocal); - [_this, false, true] call FUNC(playTreatmentAnim); - _this setVariable [QGVAR(treatmentOverAt), CBA_missionTime + 2]; - - #ifdef DEBUG_MODE_FULL - systemChat format ["%1 is giving himself morphine", _this]; - #endif - }; +if IS_UNCONSCIOUS(_this) exitWith { + _this setVariable [QGVAR(currentTreatment), nil]; }; + +[_this, _this] call FUNC(healingLogic); diff --git a/addons/medical_ai/functions/fnc_healUnit.sqf b/addons/medical_ai/functions/fnc_healUnit.sqf index 003c85a4b5..158de90f36 100644 --- a/addons/medical_ai/functions/fnc_healUnit.sqf +++ b/addons/medical_ai/functions/fnc_healUnit.sqf @@ -14,11 +14,12 @@ * * 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 -if IS_UNCONSCIOUS(_this) exitWith {}; -// Check if we're still treating -if ((_this getVariable [QGVAR(treatmentOverAt), CBA_missionTime]) > CBA_missionTime) exitWith {}; +if IS_UNCONSCIOUS(_this) exitWith { + _this setVariable [QGVAR(currentTreatment), nil]; +}; // Find next unit to treat private _healQueue = _this getVariable [QGVAR(healQueue), []]; @@ -26,74 +27,34 @@ private _target = _healQueue select 0; // If unit died or was healed, be lazy and wait for the next tick if (isNull _target || {!alive _target} || {!(_target call FUNC(isInjured))}) exitWith { + _this forceSpeed -1; _target forceSpeed -1; _healQueue deleteAt 0; - _this getVariable [QGVAR(healQueue), _healQueue]; - _this forceSpeed -1; + _this setVariable [QGVAR(healQueue), _healQueue]; // return to formation instead of going where the injured unit was if it healed itself in the mean time _this doFollow leader _this; - _this setVariable [QGVAR(movingToInjured), false]; + _this setVariable [QGVAR(nextMoveOrder), nil]; + _this setVariable [QGVAR(currentTreatment), nil]; #ifdef DEBUG_MODE_FULL - systemChat format ["%1 finished healing %2", _this, _target]; + systemChat format ["%1 finished healing %2", _this, _target]; #endif }; // Move to target... -if (_this distance _target > 2) exitWith { - if !(_this getVariable [QGVAR(movingToInjured), false]) then { - _this setVariable [QGVAR(movingToInjured), true]; +if (_this distance _target > 2.5) exitWith { + _this setVariable [QGVAR(currentTreatment), nil]; + if (CBA_missionTime >= (_this getVariable [QGVAR(nextMoveOrder), CBA_missionTime])) then { + _this setVariable [QGVAR(nextMoveOrder), CBA_missionTime + 10]; _this doMove getPosATL _target; + #ifdef DEBUG_MODE_FULL + systemChat format ["%1 moving to %2", _this, _target]; + #endif }; }; -_this setVariable [QGVAR(movingToInjured), false]; // ...and make sure medic and target don't move _this forceSpeed 0; _target forceSpeed 0; -private _needsBandaging = GET_BLOOD_LOSS(_target) > 0; -private _needsMorphine = GET_PAIN(_target) > 0.2; -private _needsEpinephrine = IS_UNCONSCIOUS(_target); - -switch (true) do { - case _needsBandaging: { - // Select first wound and bandage it - private _openWounds = _target getVariable [QEGVAR(medical,openWounds), []]; - private _partIndex = { - _x params ["", "", "_index", "_amount", "_percentage"]; - if (_amount * _percentage > 0) exitWith { - _index - }; - } forEach _openWounds; - private _selection = ALL_BODY_PARTS select _partIndex; - [_target, "BasicBandage", _selection] call EFUNC(medical_treatment,treatmentBandageLocal); - - #ifdef DEBUG_MODE_FULL - systemChat format ["%1 is bandaging selection %2 on %3", _this, _selection, _target]; - #endif - - // Play animation - [_this, true, false] call FUNC(playTreatmentAnim); - _this setVariable [QGVAR(treatmentOverAt), CBA_missionTime + 5]; - }; - case _needsMorphine: { - [_this, "Morphine", 2] call EFUNC(medical_treatment,treatmentMedicationLocal); - [_this, false, false] call FUNC(playTreatmentAnim); - _this setVariable [QGVAR(treatmentOverAt), CBA_missionTime + 2]; - - #ifdef DEBUG_MODE_FULL - systemChat format ["%1 is giving %2 morphine", _this, _target]; - #endif - }; -//ToDo - Figure out how to connect to new medical - // case _needsEpinephrine: { - // [_this, _target] call EFUNC(medical,treatmentBasic_epipen); - // [_this, false, false] call FUNC(playTreatmentAnim); - // _this setVariable [QGVAR(treatmentOverAt), CBA_missionTime + 2]; - - // #ifdef DEBUG_MODE_FULL - // systemChat format ["%1 is using an epipen on %2", _this, _target]; - // #endif - // }; -}; +[_this, _target] call FUNC(healingLogic); diff --git a/addons/medical_ai/functions/fnc_healingLogic.sqf b/addons/medical_ai/functions/fnc_healingLogic.sqf new file mode 100644 index 0000000000..d2beec1a2d --- /dev/null +++ b/addons/medical_ai/functions/fnc_healingLogic.sqf @@ -0,0 +1,117 @@ +#include "script_component.hpp" +/* + * Author: BaerMitUmlaut, PabstMirror + * Applies healing to target + * + * Arguments: + * 0: Healer + * 1: Target + * + * Return Value: + * Nothing + * + * Example: + * [a, b] call ACE_medical_ai_fnc_healingLogic + * + * Public: No + */ + +params ["_healer", "_target"]; +(_healer getVariable [QGVAR(currentTreatment), [-1]]) params ["_finishTime", "_treatmentTarget", "_treatmentEvent", "_treatmentArgs"]; + +// Treatment in progress, check if finished and apply +if (_finishTime > 0) exitWith { + if (CBA_missionTime >= _finishTime) then { + TRACE_4("treatment finished",_finishTime,_treatmentTarget,_treatmentEvent,_treatmentArgs); + _healer setVariable [QGVAR(currentTreatment), nil]; + if ((_treatmentTarget == _target) && {(_treatmentEvent select [0, 1]) != "#"}) then { + [_treatmentEvent, _treatmentArgs, _target] call CBA_fnc_targetEvent; + #ifdef DEBUG_MODE_FULL + INFO_4("%1->%2: %3 - %4",_healer,_target,_treatmentEvent,_treatmentArgs); + systemChat format ["Applying [%1->%2]: %3", _healer, _treatmentTarget, _treatmentEvent]; + #endif + }; + }; +}; + +private _isMedic = [_healer] call EFUNC(medical_treatment,isMedic); +private _heartRate = GET_HEART_RATE(_target); +private _fractures = GET_FRACTURES(_target); + +private _treatmentEvent = "#none"; +private _treatmentArgs = []; +private _treatmentTime = 6; +switch (true) do { + case (GET_WOUND_BLEEDING(_target) > 0): { + // Select first bleeding wound and bandage it + private _openWounds = GET_OPEN_WOUNDS(_target); + private _selection = "?"; + { + _x params ["", "_index", "_amount", "_percentage"]; + if ((_amount * _percentage) > 0) exitWith { _selection = ALL_BODY_PARTS select _index; }; + } forEach _openWounds; + _treatmentEvent = QEGVAR(medical_treatment,bandageLocal); + _treatmentTime = 5; + _treatmentArgs = [_target, _selection, "FieldDressing"]; + }; + case (_isMedic && {GET_BLOOD_VOLUME(_target) < BLOOD_VOLUME_CLASS_2_HEMORRHAGE}): { + private _bloodBags = _target getVariable [QEGVAR(medical,ivBags), []]; + if ((count _bloodBags) >= 2) exitWith { + _treatmentEvent = "#waitForBlood"; + }; + _treatmentEvent = QEGVAR(medical_treatment,ivBagLocal); + _treatmentTime = 5; + _treatmentArgs = [_target, selectRandom ["leftarm", "rightarm", "leftleg", "rightleg"], "SalineIV"]; + }; + case ((count (_target getVariable [VAR_MEDICATIONS, []])) >= 6): { + _treatmentEvent = "#tooManyMeds"; + }; + case ((_fractures select 4) == 1): { + _treatmentEvent = QEGVAR(medical_treatment,splintLocal); + _treatmentTime = 6; + _treatmentArgs = [_healer, _target, "leftleg"]; + }; + case ((_fractures select 5) == 1): { + _treatmentEvent = QEGVAR(medical_treatment,splintLocal); + _treatmentTime = 6; + _treatmentArgs = [_healer, _target, "rightleg"]; + }; + case (IS_UNCONSCIOUS(_target) || {_heartRate <= 50}): { + if (CBA_missionTime < (_target getVariable [QGVAR(nextEpinephrine), -1])) exitWith { + _treatmentEvent = "#waitForEpinephrineToTakeEffect"; + }; + if (_heartRate > 180) exitWith { + _treatmentEvent = "#waitForSlowerHeart"; + }; + _target setVariable [QGVAR(nextEpinephrine), CBA_missionTime + 10]; + _treatmentEvent = QEGVAR(medical_treatment,medicationLocal); + _treatmentTime = 2.5; + _treatmentArgs = [_target, selectRandom ["leftarm", "rightarm", "leftleg", "rightleg"], "Epinephrine"]; + }; + case ((GET_PAIN_PERCEIVED(_target) > 0.25) || {_heartRate >= 180}): { + if (CBA_missionTime < (_target getVariable [QGVAR(nextMorphine), -1])) exitWith { + _treatmentEvent = "#waitForMorphineToTakeEffect"; + }; + if (_heartRate < 60) exitWith { + _treatmentEvent = "#waitForFasterHeart"; + }; + _target setVariable [QGVAR(nextMorphine), CBA_missionTime + 30]; + _treatmentEvent = QEGVAR(medical_treatment,medicationLocal); + _treatmentTime = 2.5; + _treatmentArgs = [_target, selectRandom ["leftarm", "rightarm", "leftleg", "rightleg"], "Morphine"]; + }; +}; + +_healer setVariable [QGVAR(currentTreatment), [CBA_missionTime + _treatmentTime, _target, _treatmentEvent, _treatmentArgs]]; + +// Play animation +if ((_treatmentEvent select [0,1]) != "#") then { + private _treatmentClassname = _treatmentArgs select 2; + if (_treatmentEvent == QEGVAR(medical_treatment,splintLocal)) then { _treatmentClassname = "Splint" }; + [_healer, _treatmentClassname, (_healer == _target)] call FUNC(playTreatmentAnim); +}; + +#ifdef DEBUG_MODE_FULL +TRACE_4("treatment started",_treatmentTime,_target,_treatmentEvent,_treatmentArgs); +systemChat format ["Treatment [%1->%2]: %3", _healer, _target, _treatmentEvent]; +#endif diff --git a/addons/medical_ai/functions/fnc_isInjured.sqf b/addons/medical_ai/functions/fnc_isInjured.sqf index 3fa5370641..d022770f6d 100644 --- a/addons/medical_ai/functions/fnc_isInjured.sqf +++ b/addons/medical_ai/functions/fnc_isInjured.sqf @@ -17,8 +17,10 @@ if !(alive _this) exitWith {false}; -private _bloodLoss = GET_BLOOD_LOSS(_this); -private _pain = GET_PAIN_PERCEIVED(_this); -private _unconscious = IS_UNCONSCIOUS(_this); - -(_bloodLoss > 0) || {_pain > 0.2} || _unconscious +(GET_WOUND_BLEEDING(_this) > 0) +|| {GET_PAIN_PERCEIVED(_this) > 0.25} +|| {IS_UNCONSCIOUS(_this)} +|| { + private _fractures = GET_FRACTURES(_this); + ((_fractures select 4) == 1) || {(_fractures select 5) == 1} +} diff --git a/addons/medical_ai/functions/fnc_playTreatmentAnim.sqf b/addons/medical_ai/functions/fnc_playTreatmentAnim.sqf index 72a4116137..5b594edae2 100644 --- a/addons/medical_ai/functions/fnc_playTreatmentAnim.sqf +++ b/addons/medical_ai/functions/fnc_playTreatmentAnim.sqf @@ -5,7 +5,7 @@ * * Arguments: * 0: Unit - * 1: Is bandage + * 1: Treatment name * 2: Is self treatment * * Return Value: @@ -16,17 +16,12 @@ * * Public: No */ -params ["_unit", "_isBandage", "_isSelfTreatment"]; +params ["_unit", "_actionName", "_isSelfTreatment"]; +TRACE_3("playTreatmentAnim",_unit,_actionName,_isSelfTreatment); if (vehicle _unit != _unit) exitWith {}; -private _animConfig = if (_isBandage) then { - configFile >> "ACE_Medical_Actions" >> "Basic" >> "BasicBandage"; -} else { - configFile >> "ACE_Medical_Actions" >> "Basic" >> "Morphine"; -}; - -private _configProperty = "animationCaller"; +private _configProperty = "animationMedic"; if (_isSelfTreatment) then { _configProperty = _configProperty + "Self"; }; @@ -34,7 +29,9 @@ if (stance _unit == "PRONE") then { _configProperty = _configProperty + "Prone"; }; -private _anim = getText (_animConfig >> _configProperty); +private _anim = getText (configFile >> QEGVAR(medical_treatment,Actions) >> _actionName >> _configProperty); +if (_anim == "") exitWith { WARNING_2("no anim [%1, %2]",_actionName,_configProperty); }; + private _wpn = switch (true) do { case ((currentWeapon _unit) == ""): {"non"}; case ((currentWeapon _unit) == (primaryWeapon _unit)): {"rfl"}; diff --git a/addons/medical_ai/initSettings.sqf b/addons/medical_ai/initSettings.sqf index 297961872c..6fada00db5 100644 --- a/addons/medical_ai/initSettings.sqf +++ b/addons/medical_ai/initSettings.sqf @@ -1,12 +1,17 @@ +// CBA Settings [ADDON: ace_medical_ai]: + +private _categoryArray = [ELSTRING(medical,Category), "STR_TEAM_SWITCH_AI"]; + [ - QGVAR(enabledFor), - "LIST", + QGVAR(enabledFor), "LIST", [LLSTRING(enableFor_title), LLSTRING(enableFor_desc)], - LLSTRING(settingCategory), + _categoryArray, [ [0, 1, 2], [LELSTRING(Common,Disabled), LLSTRING(enabledFor_OnlyServerAndHC), LELSTRING(Common,Enabled)], 2 ], - true + true, // isGlobal + {[QGVAR(enabledFor), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart ] call CBA_settings_fnc_init; diff --git a/addons/medical_ai/stateMachine.sqf b/addons/medical_ai/stateMachine.sqf new file mode 100644 index 0000000000..48d5a6ef8e --- /dev/null +++ b/addons/medical_ai/stateMachine.sqf @@ -0,0 +1,67 @@ +GVAR(stateMachine) = [{call EFUNC(common,getLocalUnits)}, true] call CBA_statemachine_fnc_create; + +// Add states [statemachine, onState, onStateEntered, onStateLeaving, name] +[GVAR(stateMachine), {}, {}, {}, "Initial"] call CBA_statemachine_fnc_addState; + +[GVAR(stateMachine), { + #ifdef DEBUG_MODE_FULL + systemChat format ["%1 is injured", _this]; + #endif +}, {}, {}, "Injured"] call CBA_statemachine_fnc_addState; + +[GVAR(stateMachine), { + #ifdef DEBUG_MODE_FULL + systemChat format ["%1 is injured and safe", _this]; + #endif +}, {}, {}, "Safe"] call CBA_statemachine_fnc_addState; + +[GVAR(stateMachine), LINKFUNC(healSelf), {}, { + _this setVariable [QGVAR(treatmentOverAt), nil]; +}, "HealSelf"] call CBA_statemachine_fnc_addState; + +[GVAR(stateMachine), LINKFUNC(healUnit), {}, { + _this setVariable [QGVAR(treatmentOverAt), nil]; +}, "HealUnit"] call CBA_statemachine_fnc_addState; + +// Add Transistions [statemachine, originalState, targetState, condition, onTransition, name] +[GVAR(stateMachine), "Initial", "Injured", LINKFUNC(isInjured), {}, "Injured"] call CBA_statemachine_fnc_addTransition; +[GVAR(stateMachine), "Initial", "HealUnit", {(call FUNC(isSafe)) && FUNC(wasRequested)}, {}, "HealUnit"] call CBA_statemachine_fnc_addTransition; + +[GVAR(stateMachine), "Injured", "Safe", LINKFUNC(isSafe), {}, "InSafety"] call CBA_statemachine_fnc_addTransition; + +[GVAR(stateMachine), "Safe", "HealSelf", LINKFUNC(canRequestMedic), LINKFUNC(requestMedic), "RequestMedic"] call CBA_statemachine_fnc_addTransition; +[GVAR(stateMachine), "Safe", "HealSelf", {true}, {}, "HealSelf"] call CBA_statemachine_fnc_addTransition; + + +[GVAR(stateMachine), "HealSelf", "Initial", { // Go back to initial state when done healing + !(call FUNC(isInjured)) && {isNil {_this getVariable QGVAR(currentTreatment)}} +}, { + #ifdef DEBUG_MODE_FULL + systemChat format ["%1 finished healing themself", _this]; + #endif +}, "Initial"] call CBA_statemachine_fnc_addTransition; + +[GVAR(stateMachine), "HealSelf", "Injured", { // Stop treating when it's no more safe + !(call FUNC(isSafe)) && {isNil {_this getVariable QGVAR(currentTreatment)}} +}, { + #ifdef DEBUG_MODE_FULL + systemChat format ["%1 is no longer safe", _this]; + #endif +}, "Injured"] call CBA_statemachine_fnc_addTransition; + + +[GVAR(stateMachine), "HealUnit", "Initial", { // Go back to initial state when done healing or it's no more safe to treat + !((call FUNC(wasRequested)) && FUNC(isSafe)) && {isNil {_this getVariable QGVAR(currentTreatment)}} +}, { + #ifdef DEBUG_MODE_FULL + systemChat format ["%1 finished healing someone", _this]; + #endif +}, "Initial"] call CBA_statemachine_fnc_addTransition; + +[GVAR(stateMachine), "HealUnit", "Injured", { // Treating yourself has priority + (call FUNC(isInjured)) && {isNil {_this getVariable QGVAR(currentTreatment)}} +}, { + #ifdef DEBUG_MODE_FULL + systemChat format ["%1 was injured while healing someone", _this]; + #endif +}, "Injured"] call CBA_statemachine_fnc_addTransition; diff --git a/addons/medical_ai/stringtable.xml b/addons/medical_ai/stringtable.xml index e3cd9efd67..62c09e0bed 100644 --- a/addons/medical_ai/stringtable.xml +++ b/addons/medical_ai/stringtable.xml @@ -1,27 +1,35 @@ - - ACE Medical - AI - Medic AI + Sanitäts KI + AI 衛生兵 + ИИ Медик + Médecine IA + IA Médico AI will respond to injury and unconsciousness + KI reagiert auf Verletzungen und Bewusstlosigkeit + 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 Only Server and HC Nur Server und HC Sólo Server y HC - Нур сервера унд HC + Только сервер и HC サーバーと HC のみ Tylko serwer i HC - Seulement sur le server ou le HC + Seulement sur le serveur ou le HC Solo Server e HC 只在伺服器或无头客户端 只在伺服器或無頭客戶端 서버와 헤드리스만 + Apenas Servidor e HC diff --git a/addons/medical_blood/CfgEventHandlers.hpp b/addons/medical_blood/CfgEventHandlers.hpp index becf395052..0d3301d6e0 100644 --- a/addons/medical_blood/CfgEventHandlers.hpp +++ b/addons/medical_blood/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_FILE(XEH_preStart)); diff --git a/addons/medical_blood/README.md b/addons/medical_blood/README.md index 29632ffd29..848f8f0308 100644 --- a/addons/medical_blood/README.md +++ b/addons/medical_blood/README.md @@ -1,7 +1,7 @@ ace_medical_blood -=============== +================= -Adds blood visual effect on the ground near a bleeding player. +Creates blood drops on the ground near bleeding units. ## Maintainers diff --git a/addons/medical_blood/XEH_PREP.hpp b/addons/medical_blood/XEH_PREP.hpp index aa7d358388..ebed657cc5 100644 --- a/addons/medical_blood/XEH_PREP.hpp +++ b/addons/medical_blood/XEH_PREP.hpp @@ -1,7 +1,7 @@ - +PREP(cleanupLoop); +PREP(createBlood); PREP(handleWoundReceived); +PREP(init); PREP(isBleeding); PREP(onBleeding); -PREP(createBlood); -PREP(serverCleanupBlood); PREP(spurt); diff --git a/addons/medical_blood/XEH_postInit.sqf b/addons/medical_blood/XEH_postInit.sqf index c0193aa532..02201f5506 100644 --- a/addons/medical_blood/XEH_postInit.sqf +++ b/addons/medical_blood/XEH_postInit.sqf @@ -10,33 +10,18 @@ if (isServer) then { [QGVAR(bloodDropCreated), { params ["_bloodDrop"]; - // Add to created queue with format [expireTime, object] - private _index = GVAR(bloodDrops) pushBack [(CBA_missionTime + BLOOD_OBJECT_LIFETIME), _bloodDrop]; - if (count GVAR(bloodDrops) >= MAX_BLOOD_OBJECTS) then { + // Add to created queue with format: [expire time, blood object] + private _index = GVAR(bloodDrops) pushBack [CBA_missionTime + GVAR(bloodLifetime), _bloodDrop]; + + if (count GVAR(bloodDrops) >= GVAR(maxBloodObjects)) then { (GVAR(bloodDrops) deleteAt 0) params ["", "_deletedBloodDrop"]; deleteVehicle _deletedBloodDrop; }; - if (_index == 1) then { // Start the waitAndExecute loop - [FUNC(serverCleanupBlood), [], BLOOD_OBJECT_LIFETIME] call CBA_fnc_waitAndExecute; + // Start the cleanup loop + if (_index == 0) then { + [FUNC(cleanupLoop), [], GVAR(bloodLifetime)] call CBA_fnc_waitAndExecute; }; }] call CBA_fnc_addEventHandler; }; - -["ace_settingsInitialized", { - TRACE_1("settingsInitialized", GVAR(enabledFor)); - if (GVAR(enabledFor) == 0) exitWith {}; // 0: disabled - if ((GVAR(enabledFor) == 1) && {!hasInterface}) exitWith {}; // 1: enabledFor_OnlyPlayers - - private _listcode = if (GVAR(enabledFor) == 1) then { - {[ACE_player]} // ace_player is only possible local player - } else { - EFUNC(common,getLocalUnits) // filter all local units - }; - - private _stateMachine = [_listcode, true] call CBA_statemachine_fnc_create; - [_stateMachine, {call FUNC(onBleeding)}, {}, {}, "Bleeding"] call CBA_statemachine_fnc_addState; - - [QEGVAR(medical,woundReceived), FUNC(handleWoundReceived)] call CBA_fnc_addEventHandler; -}] call CBA_fnc_addEventHandler; diff --git a/addons/medical_blood/config.cpp b/addons/medical_blood/config.cpp index 5c133b9456..3e5d5227da 100644 --- a/addons/medical_blood/config.cpp +++ b/addons/medical_blood/config.cpp @@ -14,5 +14,5 @@ class CfgPatches { }; }; -#include "ACE_Settings.hpp" #include "CfgEventHandlers.hpp" +#include "ACE_Settings.hpp" diff --git a/addons/medical_blood/functions/fnc_serverCleanupBlood.sqf b/addons/medical_blood/functions/fnc_cleanupLoop.sqf similarity index 55% rename from addons/medical_blood/functions/fnc_serverCleanupBlood.sqf rename to addons/medical_blood/functions/fnc_cleanupLoop.sqf index 5a1762a7a8..e8461b2e31 100644 --- a/addons/medical_blood/functions/fnc_serverCleanupBlood.sqf +++ b/addons/medical_blood/functions/fnc_cleanupLoop.sqf @@ -1,23 +1,26 @@ #include "script_component.hpp" /* * Author: PabstMirror - * Loop that cleans up blood + * Handles cleaning up blood objects that have reached the end of their lifetime. * * Arguments: * None * - * ReturnValue: + * Return Value: * None * + * Example: + * [] call ace_medical_blood_fnc_cleanupLoop + * * Public: No */ - + (GVAR(bloodDrops) deleteAt 0) params ["", "_deletedBloodDrop"]; deleteVehicle _deletedBloodDrop; -// If we cleaned out the array, exit loop +// Exit the loop if we have cleaned out the array if (GVAR(bloodDrops) isEqualTo []) exitWith {}; // Wait until the next blood drop in the queue will expire (GVAR(bloodDrops) select 0) params ["_expireTime"]; -[FUNC(serverCleanupBlood), [], (_expireTime - CBA_missionTime)] call CBA_fnc_waitAndExecute; +[FUNC(cleanupLoop), [], _expireTime - CBA_missionTime] call CBA_fnc_waitAndExecute; diff --git a/addons/medical_blood/functions/fnc_createBlood.sqf b/addons/medical_blood/functions/fnc_createBlood.sqf index 8d3fbc8776..e54247d02e 100644 --- a/addons/medical_blood/functions/fnc_createBlood.sqf +++ b/addons/medical_blood/functions/fnc_createBlood.sqf @@ -1,15 +1,15 @@ #include "script_component.hpp" /* * Author: Glowbal - * Spawn a blood drop. + * Creates a blood object and handles its cleanup. * Available blood drop classes are blooddrop_1 through blooddrop_4. * * Arguments: - * 0: classname of blood drop + * 0: Blood Drop Type * 1: Position * * Return Value: - * Created blood drop + * Blood Drop * * Example: * ["blooddrop_2", getPos player] call ace_medical_blood_fnc_createBlood @@ -17,15 +17,15 @@ * Public: No */ -params ["_type", "_pos"]; -TRACE_2("creating blood",_type,_pos); +params ["_type", "_position"]; +TRACE_2("Creating blood",_type,_position); private _model = GVAR(models) getVariable _type; -private _object = createSimpleObject [_model, [0,0,0]]; -_object setDir random 360; -_object setPos _pos; +private _bloodDrop = createSimpleObject [_model, [0, 0, 0]]; +_bloodDrop setDir random 360; +_bloodDrop setPos _position; -[QGVAR(bloodDropCreated), [_object]] call CBA_fnc_serverEvent; +[QGVAR(bloodDropCreated), _bloodDrop] call CBA_fnc_serverEvent; -_object +_bloodDrop diff --git a/addons/medical_blood/functions/fnc_handleWoundReceived.sqf b/addons/medical_blood/functions/fnc_handleWoundReceived.sqf index 20abbd4621..7447cac52f 100644 --- a/addons/medical_blood/functions/fnc_handleWoundReceived.sqf +++ b/addons/medical_blood/functions/fnc_handleWoundReceived.sqf @@ -1,13 +1,13 @@ #include "script_component.hpp" /* * Author: Glowbal, commy2 - * Handle wounds received event. + * Handles the wounds received event by triggering any needed blood creation. * * Arguments: - * 0: unit - * 1: bodyPart - * 2: damage - * 3: shooter + * 0: Unit + * 1: Body Part (not used) + * 2: Damage + * 3: Shooter * * Return Value: * None @@ -20,16 +20,16 @@ params ["_unit", "", "_damage", "_shooter"]; -if (GVAR(enabledFor) == 1 && {!isPlayer _unit && {_unit != ACE_player}}) exitWith {}; -if (vehicle _unit != _unit && {!((vehicle _unit) isKindOf "StaticWeapon")}) exitWith {}; // Don't bleed on ground if mounted +// 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 {}; -_damage = _damage min 1; +// Don't bleed on the ground if in a vehicle +if (vehicle _unit != _unit && {!(vehicle _unit isKindOf "StaticWeapon")}) exitWith {}; -if (isNull _shooter) exitWith { // won't be able to calculate the direction properly, so instead we pick something at random - [QGVAR(spurt), [_unit, random 360, _damage]] call CBA_fnc_serverEvent; +private _bulletDir = if (isNull _shooter) then { + random 360 // Cannot calculate the direction properly, pick a random direction +} else { + _shooter getDir _unit // Calculate the bullet direction }; -// Calculate bulletDirection -private _bulletDir = _shooter getDir _unit; - -[QGVAR(spurt), [_unit, _bulletDir, _damage]] call CBA_fnc_serverEvent; +[QGVAR(spurt), [_unit, _bulletDir, _damage min 1]] call CBA_fnc_serverEvent; diff --git a/addons/medical_blood/functions/fnc_init.sqf b/addons/medical_blood/functions/fnc_init.sqf new file mode 100644 index 0000000000..336d964de7 --- /dev/null +++ b/addons/medical_blood/functions/fnc_init.sqf @@ -0,0 +1,65 @@ +#include "script_component.hpp" +/* + * Author: mharis001 + * Initializes the medical blood system based on the given mode. + * Should only be called from the CBA setting changed script. + * + * Arguments: + * 0: Mode + * + * Return Value: + * None + * + * Example: + * [2] call ace_medical_blood_fnc_init + * + * Public: No + */ + +params ["_mode"]; + +// Exit if setting is refreshed to the same value +if (!isNil QGVAR(currentSetup) && {_mode == GVAR(currentSetup)}) exitWith { + TRACE_2("Setting refreshed to current setup",GVAR(currentSetup),_mode); +}; + +// Track this new configuration that will be set up +GVAR(currentSetup) = _mode; + +// Delete current state machine if it exists +if (!isNil QGVAR(stateMachine)) then { + GVAR(stateMachine) call CBA_statemachine_fnc_delete; + GVAR(stateMachine) = nil; +}; + +// Remove wound received if it was previously added +if (!isNil QGVAR(woundReceivedEH)) then { + [QEGVAR(medical,woundReceived), GVAR(woundReceivedEH)] call CBA_fnc_removeEventHandler; + GVAR(woundReceivedEH) = nil; +}; + +// Don't need to set up anything if blood is disabled or players only on a non-player machine +if (_mode == BLOOD_DISABLED || {_mode == BLOOD_ONLY_PLAYERS && {!hasInterface}}) exitWith { + TRACE_1("Mode does not require any setup",_mode); +}; + +private _listCode = if (_mode == BLOOD_ONLY_PLAYERS) then { + // ACE_player is the only possible local player + { + if (alive ACE_player) then { + [ACE_player] + } else { + [] + }; + } +} else { + // Filter all local units + EFUNC(common,getLocalUnits) +}; + +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; + +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 b063c52ab0..14aecbb55b 100644 --- a/addons/medical_blood/functions/fnc_isBleeding.sqf +++ b/addons/medical_blood/functions/fnc_isBleeding.sqf @@ -1,13 +1,13 @@ #include "script_component.hpp" /* * Author: Glowbal - * Check if is bleeding + * Checks if the given unit is bleeding. Handles both ACE Medical and Vanilla. * * Arguments: - * 0: unit + * 0: Unit * * Return Value: - * is Bleeding + * Is Bleeding * * Example: * [player] call ace_medical_blood_fnc_isBleeding diff --git a/addons/medical_blood/functions/fnc_onBleeding.sqf b/addons/medical_blood/functions/fnc_onBleeding.sqf index 9bf27e1de4..8b6bcbb8f6 100644 --- a/addons/medical_blood/functions/fnc_onBleeding.sqf +++ b/addons/medical_blood/functions/fnc_onBleeding.sqf @@ -1,13 +1,14 @@ #include "script_component.hpp" /* * Author: Glowbal - * handle bleeding state (state machine) + * Handles periodically creating blood for a bleeding unit. + * Called from the medical_blood state machine. * * Arguments: - * 0: unit + * 0: Unit * * Return Value: - * is Bleeding + * None * * Example: * [player] call ace_medical_blood_fnc_onBleeding @@ -17,24 +18,22 @@ params ["_unit"]; -if (!([_unit] call FUNC(isBleeding))) exitWith {}; -if (((vehicle _unit) != _unit) && {!((vehicle _unit) isKindOf "StaticWeapon")}) exitWith {}; // Don't bleed on ground if mounted +// Nothing to do if unit is not bleeding +if !(_unit call FUNC(isBleeding)) exitWith {}; -private _lastTime = _unit getVariable [QGVAR(lastTime), -10]; -private _bloodLoss = (if (GVAR(useAceMedical)) then {GET_BLOOD_LOSS(_unit) * 2.5} else {getDammage _unit * 2}) min 6; -TRACE_1("",_bloodLoss); +// Don't bleed on the ground if in a vehicle +if (vehicle _unit != _unit && {!(vehicle _unit isKindOf "StaticWeapon")}) exitWith {}; -if ((CBA_missionTime - _lastTime) + _bloodLoss >= 8 + random 2) then { - _unit setVariable [QGVAR(lastTime), CBA_missionTime]; +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; + _unit setVariable [QGVAR(nextTime), CBA_missionTime + 8 + random 2 - _bloodLoss]; + + TRACE_2("Creating blood drop for bleeding unit",_unit,_bloodLoss); private _position = getPosASL _unit; - _position = _position vectorAdd [ - random 0.4 - 0.2, - random 0.4 - 0.2, - 0 - ]; + _position = _position vectorAdd [random 0.4 - 0.2, random 0.4 - 0.2, 0]; _position set [2, 0]; private _bloodDrop = ["blooddrop_1", "blooddrop_2", "blooddrop_3", "blooddrop_4"] select floor (_bloodLoss min 3); - [_bloodDrop, _position, getDir _unit] call FUNC(createBlood); + [_bloodDrop, _position] call FUNC(createBlood); }; diff --git a/addons/medical_blood/functions/fnc_spurt.sqf b/addons/medical_blood/functions/fnc_spurt.sqf index 9c6d2d1e5d..fd5c7a9fc0 100644 --- a/addons/medical_blood/functions/fnc_spurt.sqf +++ b/addons/medical_blood/functions/fnc_spurt.sqf @@ -1,18 +1,18 @@ #include "script_component.hpp" /* * Author: Sickboy - * Spurt blood on the ground + * Spurts blood on the ground based on the direction and damage. * * Arguments: - * 0: unit - * 1: direction - * 2: damage + * 0: Unit + * 1: Direction + * 2: Damage * * Return Value: * None * * Example: - * [UNIT, random 360, 1] call ace_medical_blood_fnc_spurt + * [player, random 360, 1] call ace_medical_blood_fnc_spurt * * Public: No */ @@ -21,21 +21,20 @@ #define DISTANCE_BETWEEN_DROPS 0.20 #define OFFSET 0.25 -params ["_unit", "_dir", "_damage"]; -_damage = _damage min 1; +params ["_unit", "_direction", "_damage"]; private _distanceBetweenDrops = DISTANCE_BETWEEN_DROPS * _damage; private _offset = OFFSET + _distanceBetweenDrops; -private _pos = _unit getPos [_offset, _dir]; +private _position = _unit getPos [_offset, _direction]; -["blooddrop_2", _pos, _dir] call FUNC(createBlood); +["blooddrop_2", _position, _direction] call FUNC(createBlood); private _dropAmount = ceil (MAXIMUM_DROPS * _damage); -TRACE_2("spurt blood",_dropAmount,_damage); +TRACE_2("Spurting blood",_dropAmount,_damage); if (_dropAmount > 1) then { for "_i" from 2 to _dropAmount do { - _pos = _pos getPos [_distanceBetweenDrops, _dir]; - ["blooddrop_1", _pos, _dir] call FUNC(createBlood); + _position = _position getPos [_distanceBetweenDrops, _direction]; + ["blooddrop_1", _position, _direction] call FUNC(createBlood); }; }; diff --git a/addons/medical_blood/initSettings.sqf b/addons/medical_blood/initSettings.sqf index e743002ffa..c2c52f93b8 100644 --- a/addons/medical_blood/initSettings.sqf +++ b/addons/medical_blood/initSettings.sqf @@ -1,13 +1,27 @@ -// CBA Settings [ADDON: ace_medical_blood]: - -private _categoryArray = [LELSTRING(medical,Category_DisplayName), LLSTRING(subCategory)]; +[ + QGVAR(enabledFor), + "LIST", + [LSTRING(EnabledFor_DisplayName), LSTRING(EnabledFor_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], + [[BLOOD_DISABLED, BLOOD_ONLY_PLAYERS, BLOOD_ENABLED], [ELSTRING(Common,Disabled), LSTRING(OnlyPlayers), ELSTRING(Common,Enabled)], 2], + true, + LINKFUNC(init) +] call CBA_settings_fnc_init; [ - QGVAR(enabledFor), "LIST", - [LSTRING(MedicalBloodSettings_enabledFor_DisplayName), LSTRING(MedicalBloodSettings_enabledFor_Description)], - _categoryArray, - [[0,1,2],[LELSTRING(Common,Disabled),LLSTRING(enabledFor_OnlyPlayers),LELSTRING(Common,Enabled)],2], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(enabledFor), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(maxBloodObjects), + "LIST", + [LSTRING(MaxBloodObjects_DisplayName), LSTRING(MaxBloodObjects_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], + [[50, 100, 200, 300, 400, 500, 1000, 2000, 3000, 4000, 5000], [/* settings function will auto create names */], 5], + true +] call CBA_settings_fnc_init; + +[ + QGVAR(bloodLifetime), + "TIME", + [LSTRING(BloodLifetime_DisplayName), LSTRING(BloodLifetime_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], + [1, 3600, 900], + true ] call CBA_settings_fnc_init; diff --git a/addons/medical_blood/script_component.hpp b/addons/medical_blood/script_component.hpp index ef72e2fdd5..d2bcbf9599 100644 --- a/addons/medical_blood/script_component.hpp +++ b/addons/medical_blood/script_component.hpp @@ -2,7 +2,7 @@ #define COMPONENT_BEAUTIFIED Medical Blood #include "\z\ace\addons\main\script_mod.hpp" -// #define DEBUG_ENABLED_MEDICAL_BLOOD +// #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS @@ -17,5 +17,6 @@ #include "\z\ace\addons\medical_engine\script_macros_medical.hpp" #include "\z\ace\addons\main\script_macros.hpp" -#define MAX_BLOOD_OBJECTS 500 -#define BLOOD_OBJECT_LIFETIME 900 +#define BLOOD_DISABLED 0 +#define BLOOD_ONLY_PLAYERS 1 +#define BLOOD_ENABLED 2 diff --git a/addons/medical_blood/stringtable.xml b/addons/medical_blood/stringtable.xml index 6b6df06cd4..e5ec3aa174 100644 --- a/addons/medical_blood/stringtable.xml +++ b/addons/medical_blood/stringtable.xml @@ -1,10 +1,68 @@ - - - Bleeding Effect + + + Blood + Sang + Sangre + Sangue + Krew + Кровь + Blut + Krev + Sangue + 혈흔 + 血痕 - + + Enable Blood Drops + 血痕を有効化 + Aktiviere Blutspritzer + 피흘리기 활성화 + Włącz ślady krwi na ziemi + Activer gouttes de sang + Abilita Perdite di Sangue + 开启血液滴落效果 + 開啟血液滴落效果 + Разрешить капли крови + Permitir gotas de sangue + + + 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. + + + Max Blood Objects + 最大血痕数 + Quantité sang affiché + Макс. кол-во капель крови + Limite de objetos de sangue + + + Sets the maximum number of blood drop objects which can be spawned, excessive amounts can cause FPS lag. + 生成される血痕オブジェクト数を設定できます。極端に増やすと FPS ラグを引き起こします。 + Définit le nombre maximal de traces de sangs pouvant être affichées.\nUne quantité excessive peut engendrer une baisse de FPS. + Задает макс. количество создаваемых объектов капель крови. Чрезмерное количество может вызвать задержку FPS + Define o limite máximo de objetos de gota de sangue que podem ser criados, quantidades excessivas podem causar lag de FPS. + + + Blood Lifetime + 血痕の寿命 + Durée d'affichage du sang + Время жизни капель крови + Duração do Sangue + + + 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. + + Only Players プレイヤーのみ Nur Spieler @@ -14,28 +72,8 @@ Solo Giocatori 只有玩家 只有玩家 - - - Enable Blood Drops - 血痕を有効化 - Aktiviere Blutspritzer - 피흘리기 활성화 - Włącz ślady krwi na ziemi - Active les gouttes de sang - Abilita Perdite di Sangue - 开启血液滴落效果 - 開啟血液滴落效果 - - - Enable or disable Blood Drops created on bleeding and taking damage - ダメージを受けたり、出血していると出る血痕の有効か無効化 - Aktiviere oder deaktiviere Blutspritzer, die durch Blutungen oder bei Schadensnahme entstehen. - Włącz lub wyłącz pozostawianie śladów krwi na ziemi kiedy postać odnosi obrażenia bądź krwawi - (Dés)active les gouttes de sang lors d'un saignement ou de blessure - Abilita o disabilita la Perdite di Sangue create sanguinando e prendendo danno - 开启后, 会让受伤时伤口有血液滴落的效果 - 開啟後, 會讓受傷時傷口有血液滴落的效果 - 출혈이나 부상을 입었을 때, 떨어지는 혈액을 활성화 하거나 비활성화 합니다. + Только игроки + Apenas Jogadores diff --git a/addons/medical_damage/ACE_Medical_Injuries.hpp b/addons/medical_damage/ACE_Medical_Injuries.hpp index ea15797cbe..fd03981398 100644 --- a/addons/medical_damage/ACE_Medical_Injuries.hpp +++ b/addons/medical_damage/ACE_Medical_Injuries.hpp @@ -1,4 +1,4 @@ -// bleeding - maximum possible bleeding rate for a given wound type (0 .. 1) +// bleeding - maximum possible percentage of cardiac output bled for a given wound type (0 .. 1) // pain - maximum possible pain level for a given wound type (0 .. 1) class ACE_Medical_Injuries { @@ -16,7 +16,7 @@ class ACE_Medical_Injuries { // Occur when an entire structure or part of it is forcibly pulled away, such as the loss of a permanent tooth or an ear lobe. Explosions, gunshots, and animal bites may cause avulsions. class Avulsion { causes[] = {"explosive", "vehiclecrash", "collision", "grenade", "shell", "bullet", "backblast", "bite"}; - bleeding = 0.25; + bleeding = 0.1; pain = 1.0; minDamage = 0.01; causeLimping = 1; @@ -24,7 +24,7 @@ class ACE_Medical_Injuries { // Also called bruises, these are the result of a forceful trauma that injures an internal structure without breaking the skin. Blows to the chest, abdomen, or head with a blunt instrument (e.g. a football or a fist) can cause contusions. class Contusion { causes[] = {"bullet", "backblast", "punch", "vehiclecrash", "collision", "falling"}; - bleeding = 0.0; + bleeding = 0; pain = 0.3; minDamage = 0.02; maxDamage = 0.35; @@ -36,17 +36,17 @@ class ACE_Medical_Injuries { pain = 0.8; minDamage = 0.1; causeLimping = 1; + causeFracture = 1; }; // Slicing wounds made with a sharp instrument, leaving even edges. They may be as minimal as a paper cut or as significant as a surgical incision. class Cut { causes[] = {"vehiclecrash", "collision", "grenade", "explosive", "shell", "backblast", "stab", "unknown"}; - bleeding = 0.04; + bleeding = 0.01; pain = 0.1; minDamage = 0.1; }; // Also called tears, these are separating wounds that produce ragged edges. They are produced by a tremendous force against the body, either from an internal source as in childbirth, or from an external source like a punch. class Laceration { - selections[] = {"All"}; causes[] = {"vehiclecrash", "collision", "punch"}; bleeding = 0.05; pain = 0.2; @@ -55,10 +55,11 @@ class ACE_Medical_Injuries { // Also called velocity wounds, they are caused by an object entering the body at a high speed, typically a bullet or small peices of shrapnel. class VelocityWound { causes[] = {"bullet", "grenade","explosive", "shell", "unknown"}; - bleeding = 0.5; + bleeding = 0.2; pain = 0.9; minDamage = 0.35; causeLimping = 1; + causeFracture = 1; }; // Deep, narrow wounds produced by sharp objects such as nails, knives, and broken glass. class PunctureWound { @@ -92,11 +93,11 @@ class ACE_Medical_Injuries { selectionSpecific = 0; }; class vehiclecrash { - thresholds[] = {{0.5, 5}, {0.3, 2}, {0.05, 1}}; + thresholds[] = {{1.5, 3}, {1, 2}, {0.05, 1}}; // prevent subdividing wounds past FRACTURE_DAMAGE_THRESHOLD to ensure limp/fractue is triggered selectionSpecific = 0; }; class collision { - thresholds[] = {{0.5, 5}, {0.3, 2}, {0.05, 1}}; + thresholds[] = {{1.5, 3}, {1, 2}, {0.05, 1}}; // prevent subdividing wounds past FRACTURE_DAMAGE_THRESHOLD to ensure limp/fractue is triggered selectionSpecific = 0; }; class backblast { @@ -112,8 +113,8 @@ class ACE_Medical_Injuries { selectionSpecific = 1; }; class falling { - thresholds[] = {{0.6, 4}, {0.35, 2}, {0.1, 1}}; - selectionSpecific = 1; + thresholds[] = {{1.5, 3}, {1, 2}, {0.05, 1}}; // prevent subdividing wounds past FRACTURE_DAMAGE_THRESHOLD to ensure limp/fractue is triggered + selectionSpecific = 0; }; class ropeburn { thresholds[] = {{0.1, 1}}; diff --git a/addons/medical_damage/XEH_PREP.hpp b/addons/medical_damage/XEH_PREP.hpp index ad2055ccc5..7f3a5b1102 100644 --- a/addons/medical_damage/XEH_PREP.hpp +++ b/addons/medical_damage/XEH_PREP.hpp @@ -1,3 +1,4 @@ +PREP(determineIfFatal); PREP(getTypeOfDamage); PREP(handleIncapacitation); PREP(parseConfigForInjuries); diff --git a/addons/medical_damage/XEH_preInit.sqf b/addons/medical_damage/XEH_preInit.sqf index 203f11109d..d537236aeb 100644 --- a/addons/medical_damage/XEH_preInit.sqf +++ b/addons/medical_damage/XEH_preInit.sqf @@ -17,17 +17,19 @@ addMissionEventHandler ["Loaded",{ }]; // decide which woundsHandler to use by whether the extension is present or not -if ("ace_medical" callExtension "version" != "") then { - DFUNC(woundsHandlerActive) = LINKFUNC(woundsHandler); -} else { +// if ("ace_medical" callExtension "version" != "") then { + + // DFUNC(woundsHandlerActive) = LINKFUNC(woundsHandler); +// } else { + INFO("Using woundsHandlerSQF"); DFUNC(woundsHandlerActive) = LINKFUNC(woundsHandlerSQF); -}; +// }; [QEGVAR(medical,woundReceived), { - params ["_unit", "_woundedHitPoint", "_receivedDamage", "", "_ammo"]; + params ["_unit", "_woundedHitPoint", "_receivedDamage", "", "_ammo", "_damageSelectionArray"]; private _typeOfDamage = _ammo call FUNC(getTypeOfDamage); - [_unit, _woundedHitPoint, _receivedDamage, _typeOfDamage] call FUNC(woundsHandlerActive); + [_unit, _woundedHitPoint, _receivedDamage, _typeOfDamage, _damageSelectionArray] call FUNC(woundsHandlerActive); }] call CBA_fnc_addEventHandler; ADDON = true; diff --git a/addons/medical_damage/config.cpp b/addons/medical_damage/config.cpp index 5e420a173e..cc2a1106f3 100644 --- a/addons/medical_damage/config.cpp +++ b/addons/medical_damage/config.cpp @@ -18,6 +18,10 @@ class CfgPatches { #include "ACE_Medical_Injuries.hpp" #include "CfgEventHandlers.hpp" +/* class ACE_Extensions { - extensions[] += {"ace_medical"}; + class ace_medical { + // Not yet used + }; }; + */ diff --git a/addons/medical_damage/functions/fnc_determineIfFatal.sqf b/addons/medical_damage/functions/fnc_determineIfFatal.sqf new file mode 100644 index 0000000000..fc674cf75b --- /dev/null +++ b/addons/medical_damage/functions/fnc_determineIfFatal.sqf @@ -0,0 +1,62 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror, Glowbal + * Determines if damage is fatal + * + * Arguments: + * 0: The Unit + * 1: Part No + * 2: Damage Array - QGVAR(medical,bodyPartDamage) + * 3: New Damage + * + * ReturnValue: + * Was Fatal + * + * Example: + * [player, 0, 1.4, 0.7] call ace_medical_damage_fnc_determineIfFatal + * + * Public: No + */ + +#define WEIBULL_K 6.5625 +#define WEIBULL_L 0.704523 + +params ["_unit", "_part", "_bodyPartDamage", "_woundDamage"]; + +if (_part > 1) exitWith { false }; + +scopeName "main"; + +if (EGVAR(medical,fatalDamageSource) in [0, 2]) then { + // Emulate damage to vital organs - Original rewrite logic, only powerfull headshots or random torso shots + if (_part == 0 && {_woundDamage >= HEAD_DAMAGE_THRESHOLD}) exitWith { + // Fatal damage to the head is guaranteed death + TRACE_1("determineIfFatal: lethal headshot",_woundDamage); + true breakOut "main"; + }; + if (_part == 1 && {_woundDamage >= ORGAN_DAMAGE_THRESHOLD} && {random 1 < HEART_HIT_CHANCE}) exitWith { + // Fatal damage to torso has various results based on organ hit - Heart shot is lethal + TRACE_1("determineIfFatal: lethal heartshot",_woundDamage); + true breakOut "main"; + }; +}; +if (EGVAR(medical,fatalDamageSource) in [1, 2]) then { + // Sum of trauma to critical areas can be fatal (e.g. many small hits) + private _damageThreshold = if (isPlayer _unit) then { EGVAR(medical,playerDamageThreshold) } else { EGVAR(medical,AIDamageThreshold) }; + private _headThreshhold = 1.25 * _damageThreshold; + private _bodyThreshhold = 1.5 * _damageThreshold; + + _bodyPartDamage params ["_headDamage", "_bodyDamage"]; + + private _vitalDamage = ((_headDamage - _headThreshhold) max 0) + ((_bodyDamage - _bodyThreshhold) max 0); + private _chanceFatal = 1 - exp -((_vitalDamage/WEIBULL_L)^WEIBULL_K); + TRACE_3("",_bodyPartDamage,_vitalDamage,_chanceFatal); + + if (_chanceFatal > random 1) exitWith { + TRACE_1("determineIfFatal: lethal trauma",_woundDamage); + true breakOut "main"; + }; +}; + +false + diff --git a/addons/medical_damage/functions/fnc_handleIncapacitation.sqf b/addons/medical_damage/functions/fnc_handleIncapacitation.sqf index f61b2f9c90..1a5b2a313b 100644 --- a/addons/medical_damage/functions/fnc_handleIncapacitation.sqf +++ b/addons/medical_damage/functions/fnc_handleIncapacitation.sqf @@ -24,11 +24,11 @@ _bodyPartDamage params ["_headDamage", "_bodyDamage", "_leftArmDamage", "_rightA // Exclude non penetrating body damage { - _x params ["", "", "_bodyPartN", "_amountOf", "", "_damage"]; + _x params ["", "_bodyPartN", "_amountOf", "", "_damage"]; if (_bodyPartN == 1 && {_damage < PENETRATION_THRESHOLD}) then { _bodyDamage = _bodyDamage - (_amountOf * _damage); }; -} forEach (_unit getVariable [QEGVAR(medical,openWounds), []]); +} forEach GET_OPEN_WOUNDS(_unit); private _damageThreshold = [ EGVAR(medical,AIDamageThreshold), diff --git a/addons/medical_damage/functions/fnc_parseConfigForInjuries.sqf b/addons/medical_damage/functions/fnc_parseConfigForInjuries.sqf index 682b12e141..848c78c893 100644 --- a/addons/medical_damage/functions/fnc_parseConfigForInjuries.sqf +++ b/addons/medical_damage/functions/fnc_parseConfigForInjuries.sqf @@ -19,7 +19,8 @@ private _injuriesConfigRoot = configFile >> "ACE_Medical_Injuries"; // --- parse wounds GVAR(woundClassNames) = []; -GVAR(woundsData) = []; // @todo classTypes are strings currently. Convert them to unqiue IDs instead. +GVAR(woundClassNamesComplex) = []; // index = 10 * classID + category; [will contain nils] e.g. ["aMinor", "aMed", "aLarge", nil, nil..."bMinor"] +GVAR(woundsData) = []; private _woundsConfig = _injuriesConfigRoot >> "wounds"; private _classID = 0; @@ -34,17 +35,20 @@ private _classID = 0; private _minDamage = GET_NUMBER(_entry >> "minDamage",0); private _maxDamage = GET_NUMBER(_entry >> "maxDamage",-1); private _causes = GET_ARRAY(_entry >> "causes",[]); - private _causeLimping = GET_NUMBER(_entry >> "causeLimping",0); + private _causeLimping = GET_NUMBER(_entry >> "causeLimping",0) == 1; + private _causeFracture = GET_NUMBER(_entry >> "causeFracture",0) == 1; if !(_causes isEqualTo []) then { GVAR(woundClassNames) pushBack _className; - GVAR(woundsData) pushBack [_classID, _selections, _bleeding, _pain, [_minDamage, _maxDamage], _causes, _className, _causeLimping]; + GVAR(woundsData) pushBack [_classID, _selections, _bleeding, _pain, [_minDamage, _maxDamage], _causes, _className, _causeLimping, _causeFracture]; + { + GVAR(woundClassNamesComplex) set [10 * _classID + _forEachIndex, format ["%1%2", _className, _x]]; + } forEach ["Minor", "Medium", "Large"]; _classID = _classID + 1; }; } forEach configProperties [_woundsConfig, "isClass _x"]; // --- parse damage types -GVAR(allDamageTypes) = []; // @todo, currently unused by handle damage (was GVAR(allAvailableDamageTypes)) GVAR(allDamageTypesData) = [] call CBA_fnc_createNamespace; // minimum lethal damage collection, mapped to damageTypes @@ -57,8 +61,6 @@ private _selectionSpecificDefault = getNumber (_damageTypesConfig >> "selectionS private _entry = _x; private _className = configName _entry; - GVAR(allDamageTypes) pushBack _className; - // Check if this type is in the causes of a wound class, if so, we will store the wound types for this damage type private _woundTypes = []; { @@ -74,6 +76,7 @@ private _selectionSpecificDefault = getNumber (_damageTypesConfig >> "selectionS GVAR(allDamageTypesData) setVariable [_className, [_thresholds, _selectionSpecific > 0, _woundTypes]]; + /* // extension loading private _minDamageThresholds = (_thresholds apply {str (_x select 0)}) joinString ":"; private _amountThresholds = (_thresholds apply {str (_x select 1)}) joinString ":"; @@ -89,10 +92,12 @@ private _selectionSpecificDefault = getNumber (_damageTypesConfig >> "selectionS ]; TRACE_1("",_extensionArgs); - private _extensionRes = "ace_medical" callExtension _extensionArgs; - TRACE_1("",_extensionRes); + // private _extensionRes = "ace_medical" callExtension _extensionArgs; + // TRACE_1("",_extensionRes); + */ } forEach configProperties [_damageTypesConfig, "isClass _x"]; +/* // extension loading { _x params ["_classID", "_selections", "_bleedingRate", "_pain", "_damageExtrema", "_causes", "_displayName"]; @@ -121,8 +126,9 @@ private _selectionSpecificDefault = getNumber (_damageTypesConfig >> "selectionS ]; TRACE_1("",_extensionArgs); - private _extensionRes = "ace_medical" callExtension _extensionArgs; - TRACE_1("",_extensionRes); + // private _extensionRes = "ace_medical" callExtension _extensionArgs; + // TRACE_1("",_extensionRes); } forEach GVAR(woundsData); -"ace_medical" callExtension "ConfigComplete"; +// "ace_medical" callExtension "ConfigComplete"; +*/ diff --git a/addons/medical_damage/functions/fnc_woundsHandler.sqf b/addons/medical_damage/functions/fnc_woundsHandler.sqf index 68e43f2c36..049437fdf5 100644 --- a/addons/medical_damage/functions/fnc_woundsHandler.sqf +++ b/addons/medical_damage/functions/fnc_woundsHandler.sqf @@ -18,6 +18,8 @@ * Public: No */ +WARNING("this function needs to be updated for changes to woundsHandlerSQF"); + params ["_unit", "_bodyPart", "_damage", "_typeOfDamage"]; TRACE_4("start",_unit,_bodyPart,_damage,_typeOfDamage); @@ -30,7 +32,7 @@ if (isNil {GVAR(allDamageTypesData) getVariable _typeOfDamage} ) then { }; // Administration for open wounds and ids -private _openWounds = _unit getVariable [QEGVAR(medical,openWounds), []]; +private _openWounds = GET_OPEN_WOUNDS(_unit); private _woundID = _unit getVariable [QEGVAR(medical,lastUniqueWoundID), 1]; // Unique wound ids are not used anywhere: ToDo Remove from openWounds array TRACE_4("extension call",_bodyPart,_damage,_typeOfDamage,_woundID); @@ -38,10 +40,7 @@ private _extensionOutput = "ace_medical" callExtension format ["HandleDamageWoun TRACE_1("",_extensionOutput); // these are default values and modified by _extensionOutput -private _painToAdd = 0; -private _woundsCreated = []; - -call compile _extensionOutput; +(parseSimpleArray _extensionOutput) params ["_woundsCreated", "_painToAdd"]; // todo: Make the pain and bleeding calculations part of the extension again private _woundDamage = _damage / ((count _woundsCreated) max 1); // If the damage creates multiple wounds @@ -126,7 +125,7 @@ private _bodyPartVisParams = [_unit, false, false, false, false]; // params arra }; } forEach _woundsCreated; -_unit setVariable [QEGVAR(medical,openWounds), _openWounds, true]; +_unit setVariable [VAR_OPEN_WOUNDS, _openWounds, true]; _unit setVariable [QEGVAR(medical,bodyPartDamage), _bodyPartDamage, true]; [_unit] call EFUNC(medical_status,updateWoundBloodLoss); @@ -139,4 +138,4 @@ if (_critialDamage || {_painLevel > PAIN_UNCONSCIOUS}) then { [_unit] call FUNC(handleIncapacitation); }; -TRACE_5("exit",_unit,_painLevel,GET_PAIN(_unit),_unit getVariable QEGVAR(medical,openWounds),_woundsCreated); +TRACE_5("exit",_unit,_painLevel,GET_PAIN(_unit),GET_OPEN_WOUNDS(_unit),_woundsCreated); diff --git a/addons/medical_damage/functions/fnc_woundsHandlerSQF.sqf b/addons/medical_damage/functions/fnc_woundsHandlerSQF.sqf index 88c70538a8..ee07f8508e 100644 --- a/addons/medical_damage/functions/fnc_woundsHandlerSQF.sqf +++ b/addons/medical_damage/functions/fnc_woundsHandlerSQF.sqf @@ -8,28 +8,26 @@ * 1: Name Of Body Part * 2: Amount Of Damage * 3: Type of the damage done + * 4: Weighted array of damaged selections * * Return Value: * None * * Example: - * [player, "Body", 0.5, "bullet"] call ace_medical_damage_fnc_woundsHandlerSQF + * [player, "Body", 0.5, "bullet", [1, 1]] call ace_medical_damage_fnc_woundsHandlerSQF * * Public: No */ -params ["_unit", "_bodyPart", "_damage", "_typeOfDamage"]; -TRACE_4("start",_unit,_bodyPart,_damage,_typeOfDamage); +params ["_unit", "_bodyPart", "_damage", "_typeOfDamage", "_damageSelectionArray"]; +TRACE_5("woundsHandlerSQF",_unit,_bodyPart,_damage,_typeOfDamage,_damageSelectionArray); // Convert the selectionName to a number and ensure it is a valid selection. private _bodyPartN = ALL_BODY_PARTS find toLower _bodyPart; -if (_bodyPartN < 0) exitWith {}; +if (_bodyPartN < 0) exitWith { ERROR_1("invalid body part %1",_bodyPart); }; -if (_typeOfDamage isEqualTo "") then { - _typeOfDamage = "unknown"; -}; - -if (isNil {GVAR(allDamageTypesData) getVariable _typeOfDamage} ) then { +if ((_typeOfDamage isEqualTo "") || {isNil {GVAR(allDamageTypesData) getVariable _typeOfDamage}}) then { + WARNING_1("damage type [%1] not found",_typeOfDamage); _typeOfDamage = "unknown"; }; @@ -50,7 +48,7 @@ private _allPossibleInjuries = []; // Check if the damage is higher as the min damage for the specific injury if (_damage >= _minDamage && {_damage <= _maxDamage || _maxDamage < 0}) then { // Check if the injury can be applied to the given selection name - if ("All" in _selections || {_bodyPart in _selections}) then { // @todo, this is case sensitive! + // if ("All" in _selections || {_bodyPart in _selections}) then { // @todo, this is case sensitive! [we have no injuries that use this, disabled for now] // Find the wound which has the highest minimal damage, so we can use this later on for adding the correct injuries if (_minDamage > _highestPossibleDamage) then { @@ -60,124 +58,126 @@ private _allPossibleInjuries = []; // Store the valid possible injury for the damage type, damage amount and selection _allPossibleInjuries pushBack _x; - }; + // }; }; } forEach _woundTypes; // No possible wounds available for this damage type or damage amount. -if (_highestPossibleSpot < 0) exitWith {}; +if (_highestPossibleSpot < 0) exitWith { TRACE_2("no wounds possible",_damage,_highestPossibleSpot); }; // Administration for open wounds and ids -private _openWounds = _unit getVariable [QEGVAR(medical,openWounds), []]; -private _woundID = _unit getVariable [QEGVAR(medical,lastUniqueWoundID), 1]; // Unique wound ids are not used anywhere: ToDo Remove from openWounds array +private _openWounds = GET_OPEN_WOUNDS(_unit); +private _updateDamageEffects = false; private _painLevel = 0; private _critialDamage = false; private _bodyPartDamage = _unit getVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]]; private _bodyPartVisParams = [_unit, false, false, false, false]; // params array for EFUNC(medical_engine,updateBodyPartVisuals); -private _woundsCreated = []; + { _x params ["_thresholdMinDam", "_thresholdWoundCount"]; - if (_thresholdMinDam <= _damage) exitWith { + if (_damage > _thresholdMinDam) exitWith { private _woundDamage = _damage / (_thresholdWoundCount max 1); // If the damage creates multiple wounds - for "_i" from 0 to (_thresholdWoundCount-1) do { - // Find the injury we are going to add. Format [ classID, allowdSelections, bleedingRate, injuryPain] - private _oldInjury = if (random 1 >= 0.85) then { + for "_i" from 1 to _thresholdWoundCount do { + // Find the injury we are going to add. Format [ classID, allowedSelections, bleedingRate, injuryPain] + private _oldInjury = if (random 1 < 0.15) then { _woundTypes select _highestPossibleSpot } else { selectRandom _allPossibleInjuries }; - _oldInjury params ["_woundClassIDToAdd", "", "_injuryBleedingRate", "_injuryPain"]; + _oldInjury params ["_woundClassIDToAdd", "", "_injuryBleedingRate", "_injuryPain", "", "", "", "_causeLimping", "_causeFracture"]; - private _bodyPartNToAdd = [floor random 6, _bodyPartN] select _isSelectionSpecific; // 6 == count ALL_BODY_PARTS + private _bodyPartNToAdd = if (_isSelectionSpecific) then {_bodyPartN} else {selectRandomWeighted _damageSelectionArray}; _bodyPartDamage set [_bodyPartNToAdd, (_bodyPartDamage select _bodyPartNToAdd) + _woundDamage]; _bodyPartVisParams set [[1,2,3,3,4,4] select _bodyPartNToAdd, true]; // Mark the body part index needs updating - // Create a new injury. Format [ID, classID, bodypart, percentage treated, bleeding rate] - private _injury = [_woundID, _woundClassIDToAdd, _bodyPartNToAdd, 1, _injuryBleedingRate]; - // The higher the nastiness likelihood the higher the change to get a painful and bloody wound - private _nastinessLikelihood = linearConversion [0, 20, (_woundDamage / _thresholdWoundCount), 0.5, 30, true]; - private _bleedingModifier = 0.25 + 8 * exp ((random [-4.5, -5, -6]) / _nastinessLikelihood); - private _painModifier = 0.05 + 2 * exp (-2 / _nastinessLikelihood); + // Damage to limbs/head is scaled higher than torso by engine + // Anything above this value is guaranteed worst wound possible + private _worstDamage = [2, 1, 4, 4, 4, 4] select _bodyPartNToAdd; - private _bleeding = _injuryBleedingRate * _bleedingModifier; + // More wounds means more likely to get nasty wound + private _countModifier = 1 + random(_i - 1); + + // Config specifies bleeding and pain for worst possible wound + // Worse wound correlates to higher damage, damage is not capped at 1 + private _bleedModifier = linearConversion [0.1, _worstDamage, _woundDamage * _countModifier, 0.25, 1, true]; + private _painModifier = (_bleedModifier * random [0.7, 1, 1.3]) min 1; // Pain isn't directly scaled to bleeding + + private _bleeding = _injuryBleedingRate * _bleedModifier; private _pain = _injuryPain * _painModifier; _painLevel = _painLevel + _pain; - // wound category (minor [0..0.5], medium[0.5..1.0], large[1.0+]) - private _category = floor linearConversion [0, 1, _bleedingModifier, 0, 2, true]; + // wound category (minor [0.25-0.5], medium [0.5-0.75], large [0.75+]) + private _category = floor linearConversion [0.25, 0.75, _bleedModifier, 0, 2, true]; - // wound category (minor, medium, large) - private _category = floor ((0 max _bleeding min 0.1) / 0.05); + private _classComplex = 10 * _woundClassIDToAdd + _category; - _injury set [4, _bleeding]; - _injury set [5, _woundDamage]; - _injury set [6, _category]; + // Create a new injury. Format [0:classComplex, 1:bodypart, 2:amountOf, 3:bleedingRate, 4:woundDamage] + private _injury = [_classComplex, _bodyPartNToAdd, 1, _bleeding, _woundDamage]; if (_bodyPartNToAdd == 0 || {_bodyPartNToAdd == 1 && {_woundDamage > PENETRATION_THRESHOLD}}) then { _critialDamage = true; }; -#ifdef DEBUG_MODE_FULL - systemChat format["%1, damage: %2, peneration: %3, bleeding: %4, pain: %5", _bodyPart, _woundDamage toFixed 2, _woundDamage > PENETRATION_THRESHOLD, _bleeding toFixed 3, _pain toFixed 3]; -#endif - - // Emulate damage to vital organs - switch (true) do { - // Fatal damage to the head is guaranteed death - case (_bodyPartNToAdd == 0 && {_woundDamage >= HEAD_DAMAGE_THRESHOLD}): { - TRACE_1("lethal headshot",_woundDamage toFixed 2); - [QEGVAR(medical,FatalInjury), _unit] call CBA_fnc_localEvent; - }; - // Fatal damage to torso has various results based on organ hit - case (_bodyPartNToAdd == 1 && {_woundDamage >= ORGAN_DAMAGE_THRESHOLD}): { - // Heart shot is lethal - if (random 1 < HEART_HIT_CHANCE) then { - TRACE_1("lethal heartshot",_woundDamage toFixed 2); - [QEGVAR(medical,FatalInjury), _unit] call CBA_fnc_localEvent; - }; - }; + if ([_unit, _bodyPartNToAdd, _bodyPartDamage, _woundDamage] call FUNC(determineIfFatal)) then { + TRACE_1("determineIfFatal returned true",_woundDamage); + [QEGVAR(medical,FatalInjury), _unit] call CBA_fnc_localEvent; }; - // todo `forceWalk` based on leg damage - private _causeLimping = (GVAR(woundsData) select _woundClassIDToAdd) select 7; - if (_causeLimping == 1 && {_woundDamage > LIMPING_DAMAGE_THRESHOLD} && {_bodyPartNToAdd > 3}) then { - [_unit, true] call EFUNC(medical_engine,setLimping); + #ifdef DEBUG_MODE_FULL + systemChat format["%1, damage: %2, peneration: %3, bleeding: %4, pain: %5", _bodyPart, _woundDamage toFixed 2, _woundDamage > PENETRATION_THRESHOLD, _bleeding toFixed 3, _pain toFixed 3]; + #endif + + switch (true) do { + case (_causeFracture && {EGVAR(medical,fractures) > 0} && {_bodyPartNToAdd > 1} && {_woundDamage > FRACTURE_DAMAGE_THRESHOLD}): { + TRACE_1("limb fracture",_bodyPartNToAdd); + private _fractures = GET_FRACTURES(_unit); + _fractures set [_bodyPartNToAdd, 1]; + _unit setVariable [VAR_FRACTURES, _fractures, true]; + [QEGVAR(medical,fracture), [_unit, _bodyPartNToAdd]] call CBA_fnc_localEvent; // local event for fracture + _updateDamageEffects = true; + }; + case (_causeLimping && {EGVAR(medical,limping) > 0} && {_bodyPartNToAdd > 3} && {_woundDamage > LIMPING_DAMAGE_THRESHOLD}): { + _updateDamageEffects = true; + }; }; // if possible merge into existing wounds private _createNewWound = true; { - _x params ["", "_classID", "_bodyPartN", "_oldAmountOf", "_oldBleeding", "_oldDamage", "_oldCategory"]; - if (_woundClassIDToAdd == _classID && {_bodyPartNToAdd == _bodyPartN && {(_woundDamage < PENETRATION_THRESHOLD) isEqualTo (_oldDamage < PENETRATION_THRESHOLD)}}) then { - if (_oldCategory == _category) exitWith { - private _newAmountOf = _oldAmountOf + 1; - _x set [3, _newAmountOf]; - private _newBleeding = (_oldAmountOf * _oldBleeding + _bleeding) / _newAmountOf; - _x set [4, _newBleeding]; - private _newDamage = (_oldAmountOf * _oldDamage + _woundDamage) / _newAmountOf; - _x set [5, _newDamage]; - _createNewWound = false; - }; + _x params ["_classID", "_bodyPartN", "_oldAmountOf", "_oldBleeding", "_oldDamage"]; + if ( + (_classComplex == _classID) && + {_bodyPartNToAdd == _bodyPartN} && + {(_bodyPartNToAdd != 1) || {(_woundDamage < PENETRATION_THRESHOLD) isEqualTo (_oldDamage < PENETRATION_THRESHOLD)}} && // penetrating body damage is handled differently + {(_bodyPartNToAdd > 3) || {!_causeLimping} || {(_woundDamage <= LIMPING_DAMAGE_THRESHOLD) isEqualTo (_oldDamage <= LIMPING_DAMAGE_THRESHOLD)}} // ensure limping damage is stacked correctly + ) exitWith { + TRACE_2("merging with existing wound",_injury,_x); + private _newAmountOf = _oldAmountOf + 1; + _x set [2, _newAmountOf]; + private _newBleeding = (_oldAmountOf * _oldBleeding + _bleeding) / _newAmountOf; + _x set [3, _newBleeding]; + private _newDamage = (_oldAmountOf * _oldDamage + _woundDamage) / _newAmountOf; + _x set [4, _newDamage]; + _createNewWound = false; }; } forEach _openWounds; if (_createNewWound) then { + TRACE_1("adding new wound",_injury); _openWounds pushBack _injury; }; - - // New injuries will also increase the wound ID - _woundID = _woundID + 1; - - // Store the injury so we can process it later correctly. - _woundsCreated pushBack _injury; }; }; } forEach _thresholds; -_unit setVariable [QEGVAR(medical,openWounds), _openWounds, true]; +if (_updateDamageEffects) then { + [_unit] call EFUNC(medical_engine,updateDamageEffects); +}; + +_unit setVariable [VAR_OPEN_WOUNDS, _openWounds, true]; _unit setVariable [QEGVAR(medical,bodyPartDamage), _bodyPartDamage, true]; [_unit] call EFUNC(medical_status,updateWoundBloodLoss); @@ -190,4 +190,4 @@ if (_critialDamage || {_painLevel > PAIN_UNCONSCIOUS}) then { [_unit] call FUNC(handleIncapacitation); }; -TRACE_5("exit",_unit,_painLevel,GET_PAIN(_unit),_unit getVariable QEGVAR(medical,openWounds),_woundsCreated); +TRACE_4("exit",_unit,_painLevel,GET_PAIN(_unit),GET_OPEN_WOUNDS(_unit)); diff --git a/addons/medical_damage/initSettings.sqf b/addons/medical_damage/initSettings.sqf index 88a1283cf7..e508f74621 100644 --- a/addons/medical_damage/initSettings.sqf +++ b/addons/medical_damage/initSettings.sqf @@ -1,23 +1,26 @@ -// CBA Settings [ADDON: ace_medical_damage]: - -private _categoryArray = [LELSTRING(medical,Category_DisplayName), LLSTRING(subCategory)]; - [ - QEGVAR(medical,playerDamageThreshold), "SLIDER", - [LSTRING(playerDamageThreshold_DisplayName), LSTRING(playerDamageThreshold_Description)], - _categoryArray, - [0,25,1,2], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QEGVAR(medical,playerDamageThreshold), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QEGVAR(medical,fatalDamageSource), + "LIST", + [LSTRING(fatalDamageSource_DisplayName), LSTRING(fatalDamageSource_Description)], + [ELSTRING(medical,Category)], + [[0, 1, 2], [LSTRING(fatalDamageSource_vitalShotsOnly), LSTRING(fatalDamageSource_trauma), LSTRING(fatalDamageSource_both)], 0], + true ] call CBA_settings_fnc_init; [ - QEGVAR(medical,AIDamageThreshold), "SLIDER", + QEGVAR(medical,playerDamageThreshold), + "SLIDER", + [LSTRING(PlayerDamageThreshold_DisplayName), LSTRING(PlayerDamageThreshold_Description)], + ELSTRING(medical,Category), + [0, 25, 1, 2], + true +] call CBA_settings_fnc_init; + +[ + QEGVAR(medical,AIDamageThreshold), + "SLIDER", [LSTRING(AIDamageThreshold_DisplayName), LSTRING(AIDamageThreshold_Description)], - _categoryArray, - [0,25,1,2], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QEGVAR(medical,AIDamageThreshold), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + ELSTRING(medical,Category), + [0, 25, 1, 2], + true ] call CBA_settings_fnc_init; diff --git a/addons/medical_damage/script_component.hpp b/addons/medical_damage/script_component.hpp index c567aeeae7..272dc7d565 100644 --- a/addons/medical_damage/script_component.hpp +++ b/addons/medical_damage/script_component.hpp @@ -4,7 +4,7 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -//#define ENABLE_PERFORMANCE_COUNTERS +// #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_MEDICAL_DAMAGE #define DEBUG_MODE_FULL diff --git a/addons/medical_damage/stringtable.xml b/addons/medical_damage/stringtable.xml index d1d20c0032..6ac2818879 100644 --- a/addons/medical_damage/stringtable.xml +++ b/addons/medical_damage/stringtable.xml @@ -1,81 +1,40 @@ - - - Damage Threshold - - - Player Damage - Урон игроку - Próg obrażeń graczy - Daño de jugador - Spielerschaden - Poškození hráče - Dano do jogador - Dégats du joueur - Játékos sérülés - Danno Giocatore - プレイヤーへの損傷 - 플레이어 부상 - 玩家伤害 - 玩家傷害 - - - What is the damage a player can take before being killed? - Какой уровень урона необходим, чтобы убить игрока? - Jaki jest próg obrażeń, jakie gracz może otrzymać zanim zostanie zabity? - ¿Cuál es el daño que un jugador puede sufrir antes de morir? - Wie viel Schaden kann ein Spieler erleiden, bevor er getötet wird? - Jaké poškození může hráč dostat než bude zabit? - Qal é o dano que um jogador pode sofrer antes de morrer? - Quels dégâts peut subir un joueur avant d'être tué - Mennyi sérülést szenvedhet el egy játékos, mielőtt meghal? - Quanto è il danno che un giocatore può sostenere prima di essere ucciso? - プレイヤーが死に始める前に損傷を受けるようにしますか? - 얼마정도의 부상을 플레이어가 죽기 전까지 버틸 수 있습니까? - 玩家死亡前所能承受的伤害程度 - 玩家死亡前所能承受的傷害程度 - - - AI Damage - Урон ботам - Próg obrażeń AI - Daño IA - KI-Schaden - Poškození AI - Dano da IA - Dégâts des IA - AI sérülés - Danno AI - AI への損傷 - 인공지능 부상 - AI伤害 - AI傷害 - - - What is the damage an AI can take before being killed? - Какой уровень урона необходим, чтобы убить бота? - Jaki jest próg obrażeń, jakie AI może otrzymać zanim zostanie zabite? - ¿Cuál es el daño que la IA puede sufrir antes de morir? - Wie viel Schaden kann eine KI erleiden, bis sie getötet wird? - Jaké poškození může AI dostat než bude zabito? - Qual é o dano que uma IA pode sofrer antes de morrer? - Quels dégâts peut subir une IA avant d'être tuée - Mennyi sérülést szenvedhet el egy AI, mielőtt meghal? - Quanto è il danno che un'IA può sostenere prima di essere uccisa? - AI が死に始める前に損傷を受けるようにしますか? - 얼마정도의 부상을 인공지능이 죽기 전까지 버틸 수 있습니까? - AI 死亡前所能承受的伤害程度 - AI 死亡前所能承受的傷害程度 - - + + Player Critical Damage Threshold + プレイヤーのクリティカル ダメージしきい値 + Seuil de dégât critique du joueur + Порог критического урона игрока + Limite de Dano Crítico do Jogador + + + Sets the amount of damage a player can receive before going unconscious. + プレイヤーが気絶になる前に受けられるダメージ量を決定できます。 + Définit la quantité de dégâts qu'un joueur peut subir avant de perdre connaissance. + Устанавливает количество урона, которое может получить игрок, прежде чем потеряет сознание. + Define a quantidade de dano que um jogador pode receber antes de ficar inconsciente. + + + AI Critical Damage Threshold + AI のクリティカル ダメージしきい値 + Seuil de dégât critique de l'IA + Порог критического урона AI + Limite de Dano Crítico da IA + + + Sets the amount of damage an AI unit can receive before going unconscious. + AI が気絶になる前に受けられるダメージ量を決定できます。 + Définit la quantité de dégâts qu'une unité IA peut subir avant de perdre connaissance. + Устанавливает количество урона, которое может получить ИИ, прежде чем потеряет сознание. + Define a quantidade de dano que uma IA pode receber antes de ficar inconsciente. + Scrape Kratzer Scorticatura Ссадина - Eraflure + Écorchure Draśnięcie Arañazo Horzsolás @@ -89,7 +48,7 @@ Kleiner Kratzer Minima Scorticatura Малая ссадина - Petite éraflure + Petite écorchure Pomniejsze draśnięcie Arañazo menor Kis horzsolás @@ -103,7 +62,7 @@ Mittlerer Kratzer Media Scorticatura Средняя ссадина - Moyenne éraflure + Moyenne écorchure Średnie draśnięcie Arañazo medio Közepes horzsolás @@ -117,7 +76,7 @@ Großer Kratzer Alta Scorticatura Большая ссадина - Grande éraflure + Grande écorchure Duże draśnięcie Arañazo severo Nagy horzsolás @@ -215,7 +174,7 @@ Mittlere Prellung Media Contusione Средний ушиб - Hématome moyen + Moyen hématome Średnie stłuczenie Contusión media Közepes zúzódás @@ -229,7 +188,7 @@ Große Prellung Alta Contusione Большой ушиб - Hématome important + Grand Hématome Duże stłuczenie Contusión severa Nagy zúzódás @@ -257,7 +216,7 @@ Kleine Quetschverletzung Minimo Tessuto Schiacciato Малая компрессионная травма - Tissu écrasé léger + Tissu légèrement écrasé Pomniejsze zgniecienie tkanek miękkich Tejido triturado menor Kis zúzott szövet @@ -271,7 +230,7 @@ Mittlere Quetschverletzung Medio Tessuto Schiacciato Средняя компрессионная травма - Tissu écrasé moyen + Tissu moyennement écrasé Średnie zgniecienie tkanek miękkich Tejido triturado medio Közepes zúzott szövet @@ -285,7 +244,7 @@ Große Quetschverletzung Alto Tessuto Schiacciato Большая компрессионная травма - Tissu écrasé large + Tissu fortement écrasé Duże zgniecienie tkanek miękkich Tejido triturado severo Nagy zúzött szövet @@ -330,7 +289,7 @@ Średnia rana cięta Corte mediano Közepes vágás - Moyenne coupure + Coupure moyenne Corte médio Střední řezná rána 中くらいの切り傷 @@ -356,7 +315,7 @@ Strappo Рваная рана Rozerwanie skóry - Déchirure + Lacération Desgarro Szakadás Ruptura @@ -370,7 +329,7 @@ Piccolo Strappo Малая рваная рана Pomniejsze rozerwanie skóry - Petite Déchirure + Petite lacération Desgarro menor Kis szakadás Ruptura leve @@ -386,7 +345,7 @@ Średnie rozerwanie skóry Desgarro medio Közepes szakadás - Moyenne déchirure + Moyenne lacération Ruptura média Střední tržná rána 中くらいの裂傷 @@ -400,7 +359,7 @@ Duże rozerwanie skóry Desgarro severo Nagy szakadás - Large déchirure + Grande lacération Ruptura grave Velká tržná rána 大きな裂傷 @@ -412,7 +371,7 @@ Velocità Ferita Огнестрельная рана Rana postrzałowa - Blessure de vélocité + Plaie pénétrante Herida de bala Lőtt seb Ferimento por projétil de arma de fogo @@ -428,7 +387,7 @@ Pomniejsza rana postrzałowa Herida de bala menor Kis lőtt seb - Petite blessure de vélocité + Petite plaie pénétrante Ferimento leve por projétil de arma de fogo Malé střelné poranění 小さな銃創 @@ -442,7 +401,7 @@ Średnia rana postrzałowa Herida de bala media Közepes lőtt seb - Moyenne blessure de vélocité + Plaie moyenne pénétrante Ferimento médio por projétil de arma de fogo Střední střelné poranění 中くらいの銃創 @@ -456,7 +415,7 @@ Duża rana postrzałowa Herida de bala severa Nagy lőtt seb - Large blessure de vélocité + Grande plaie pénétrante Ferimento grave por projétil de arma de fogo Velké střelné poranění 大きな銃創 @@ -468,7 +427,7 @@ Puntura Ferita Колотая рана Rana kłuta - Blessure de perforation + Blessure par perforation Herida punzante Szúrt seb Ferimento por perfuração @@ -484,7 +443,7 @@ Pomniejsza rana kłuta Herida punzante menor Kis szúrt seb - Légère blessure de perforation + Petite perforation Ferimento leve por perfuração Malá bodná rána 小さな刺し傷 @@ -498,7 +457,7 @@ Średnia rana kłuta Herida punzante media Közepes szúrt seb - Moyenne blessure de perforation + Moyenne perforation Ferimento médio por perfuração Střední bodná rána 中くらいの刺し傷 @@ -512,11 +471,26 @@ Duża rana kłuta Herida punzante severa Nagy szúrt seb - Large blessure de perforation + Grande perforation Ferimento grave por perfuração Velká bodná rána 大きな刺し傷 대형 관통상 + + Fatal Damage Source + + + Determines what damage can be fatal + + + Only large hits to vital organs + + + Sum of trauma + + + Either + diff --git a/addons/medical_engine/CfgVehicles.hpp b/addons/medical_engine/CfgVehicles.hpp index 3cccea2c3f..58a4b47114 100644 --- a/addons/medical_engine/CfgVehicles.hpp +++ b/addons/medical_engine/CfgVehicles.hpp @@ -63,6 +63,11 @@ class CfgVehicles { ADD_ACE_HITPOINTS(1,1); }; }; + class B_Protagonist_VR_F: B_Soldier_base_F { + class HitPoints { + ADD_ACE_HITPOINTS(1,1); + }; + }; class O_Soldier_VR_F: O_Soldier_base_F { class HitPoints { ADD_ACE_HITPOINTS(1,1); @@ -73,10 +78,7 @@ class CfgVehicles { ADD_ACE_HITPOINTS(1,1); }; }; - - // Civilians - class C_man_1; - class C_Soldier_VR_F: C_man_1 { + class I_Protagonist_VR_F: I_Soldier_base_F { class HitPoints { ADD_ACE_HITPOINTS(1,1); }; @@ -86,6 +88,19 @@ class CfgVehicles { ADD_ACE_HITPOINTS(1,1); }; }; + class C_man_1; + class C_Protagonist_VR_F: C_man_1 { + class HitPoints { + ADD_ACE_HITPOINTS(1,1); + }; + }; + + // Civilians + class C_Soldier_VR_F: C_man_1 { + class HitPoints { + ADD_ACE_HITPOINTS(1,1); + }; + }; // APEX class O_V_Soldier_Viper_F: O_Soldier_base_F { diff --git a/addons/medical_engine/XEH_PREP.hpp b/addons/medical_engine/XEH_PREP.hpp index 3c7872c515..0bacdd97e7 100644 --- a/addons/medical_engine/XEH_PREP.hpp +++ b/addons/medical_engine/XEH_PREP.hpp @@ -1,6 +1,6 @@ PREP(handleDamage); PREP(damageBodyPart); PREP(updateBodyPartVisuals); -PREP(setLimping); +PREP(updateDamageEffects); PREP(setStructuralDamage); PREP(setUnconsciousAnim); diff --git a/addons/medical_engine/XEH_postInit.sqf b/addons/medical_engine/XEH_postInit.sqf index b7dccbeb56..2a6aa2b717 100644 --- a/addons/medical_engine/XEH_postInit.sqf +++ b/addons/medical_engine/XEH_postInit.sqf @@ -1,5 +1,12 @@ #include "script_component.hpp" +[QGVAR(updateDamageEffects), LINKFUNC(updateDamageEffects)] call CBA_fnc_addEventHandler; +["unit", { + params ["_new"]; + [_new] call FUNC(updateDamageEffects); // Run on new controlled unit to update QGVAR(aimFracture) +}, true] call CBA_fnc_addPlayerEventHandler; + + ["CAManBase", "init", { params ["_unit"]; diff --git a/addons/medical_engine/functions/fnc_handleDamage.sqf b/addons/medical_engine/functions/fnc_handleDamage.sqf index 3ff3065471..000c90b911 100644 --- a/addons/medical_engine/functions/fnc_handleDamage.sqf +++ b/addons/medical_engine/functions/fnc_handleDamage.sqf @@ -80,13 +80,25 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { ]; TRACE_2("incoming",_allDamages,_damageStructural); + // represents all incoming damage for selecting a non-selectionSpecific wound location, (used for selectRandomWeighted [value1,weight1,value2....]) + private _damageSelectionArray = [ + HITPOINT_INDEX_HEAD, _damageHead, HITPOINT_INDEX_BODY, _damageBody, HITPOINT_INDEX_LARM, _damageLeftArm, + HITPOINT_INDEX_RARM, _damageRightArm, HITPOINT_INDEX_LLEG, _damageLeftLeg, HITPOINT_INDEX_RLEG, _damageRightLeg + ]; + _allDamages sort false; (_allDamages select 0) params ["_receivedDamage", "", "_woundedHitPoint"]; + if (_damageHead >= HEAD_DAMAGE_THRESHOLD) then { + TRACE_3("reporting fatal head damage instead of max",_damageHead,_receivedDamage,_woundedHitPoint); + _receivedDamage = _damageHead; + _woundedHitPoint = "Head"; + }; // We know it's structural when no specific hitpoint is damaged if (_receivedDamage == 0) then { _receivedDamage = _damageStructural; _woundedHitPoint = "Body"; + _damageSelectionArray = [1, 1]; // sum of weights would be 0 }; // Environmental damage sources all have empty ammo string @@ -95,7 +107,7 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { // Any collision with terrain/vehicle/object has a shooter // Check this first because burning can happen at any velocity if !(isNull _shooter) then { - _ammo = "#collision"; + _ammo = "#collision"; // non-selectionSpecific so only _damageSelectionArray matters /* If shooter != unit then they hit unit, otherwise it could be: @@ -105,10 +117,11 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { Assume fall damage for downward velocity because it's most common */ if (_shooter == _unit && {(velocity _unit select 2) < -2}) then { - _woundedHitPoint = selectRandom ["RightLeg", "LeftLeg"]; + _ammo = "#falling"; // non-selectionSpecific so only _damageSelectionArray matters + _damageSelectionArray = [4, 1, 5, 1]; // selectRandom ["RightLeg", "LeftLeg"]; TRACE_5("Fall",_unit,_shooter,_instigator,_damage,_receivedDamage); } else { - _woundedHitPoint = selectRandom ["RightArm", "LeftArm", "RightLeg", "LeftLeg"]; + _damageSelectionArray = [2, 1, 3, 1, 4, 1, 5, 1]; // selectRandom ["RightArm", "LeftArm", "RightLeg", "LeftLeg"]; TRACE_5("Collision",_unit,_shooter,_instigator,_damage,_receivedDamage); }; @@ -117,12 +130,16 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { // Higher momentum results in higher chance for head to be hit for more lethality if (_receivedDamage > 0.35) then { private _headHitWeight = (_receivedDamage / 2) min 1; - _woundedHitPoint = selectRandomWeighted ["Body", (1 - _headHitWeight), "Head", _headHitWeight]; + if (_recievedDamage < 0.6) then { + _damageSelectionArray append [0, (1 - _headHitWeight), 1, _headHitWeight]; + } else { + _damageSelectionArray = [0, (1 - _headHitWeight), 1, _headHitWeight]; + } }; } else { // Anything else is almost guaranteed to be fire damage - _woundedHitPoint = selectRandom ["LeftLeg", "RightLeg", "Body"]; - _ammo = "#unknown"; + _damageSelectionArray = [1, 1, 4, 1, 5, 1]; // selectRandom ["Body", "LeftLeg", "RightLeg"]; + _ammo = "#unknown"; // non-selectionSpecific so only _damageSelectionArray matters // Fire damage can occur as lots of minor damage events // Combine these until significant enough to wound @@ -140,8 +157,8 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { // No wounds for minor damage if (_receivedDamage > 1E-3) then { - [QEGVAR(medical,woundReceived), [_unit, _woundedHitPoint, _receivedDamage, _shooter, _ammo]] call CBA_fnc_localEvent; - TRACE_2("received",_receivedDamage,_woundedHitPoint); + TRACE_3("received",_receivedDamage,_woundedHitPoint,_damageSelectionArray); + [QEGVAR(medical,woundReceived), [_unit, _woundedHitPoint, _receivedDamage, _shooter, _ammo, _damageSelectionArray]] call CBA_fnc_localEvent; }; // Clear stored damages otherwise they will influence future damage events @@ -164,7 +181,7 @@ if ( {getOxygenRemaining _unit <= 0.5} && {_damage isEqualTo (_oldDamage + 0.005)} ) exitWith { - [QEGVAR(medical,woundReceived), [_unit, "Body", _newDamage, _unit, "#drowning"]] call CBA_fnc_localEvent; + [QEGVAR(medical,woundReceived), [_unit, "Body", _newDamage, _unit, "#drowning", [HITPOINT_INDEX_BODY, 1]]] call CBA_fnc_localEvent; TRACE_5("Drowning",_unit,_shooter,_instigator,_damage,_newDamage); 0 @@ -180,7 +197,11 @@ if ( {vectorMagnitude (velocity _vehicle) > 5} // todo: no way to detect if stationary and another vehicle hits you ) exitWith { - [QEGVAR(medical,woundReceived), [_unit, "Body", _newDamage, _unit, "#vehiclecrash"]] call CBA_fnc_localEvent; + private _damageSelectionArray = [ + HITPOINT_INDEX_HEAD, 1, HITPOINT_INDEX_BODY, 1, HITPOINT_INDEX_LARM, 1, + HITPOINT_INDEX_RARM, 1, HITPOINT_INDEX_LLEG, 1, HITPOINT_INDEX_RLEG, 1 + ]; + [QEGVAR(medical,woundReceived), [_unit, "Body", _newDamage, _unit, "#vehiclecrash", _damageSelectionArray]] call CBA_fnc_localEvent; TRACE_5("Crash",_unit,_shooter,_instigator,_damage,_newDamage); 0 diff --git a/addons/medical_engine/functions/fnc_setLimping.sqf b/addons/medical_engine/functions/fnc_setLimping.sqf deleted file mode 100644 index 11ead53c54..0000000000 --- a/addons/medical_engine/functions/fnc_setLimping.sqf +++ /dev/null @@ -1,30 +0,0 @@ -#include "script_component.hpp" -/* - * Author: commy2 - * Forces a unit to limp or not. - * - * Arguments: - * 0: Unit - * 1: Limping (optional, default: true) - * - * Return Value: - * None - * - * Example: - * [player, true] call ace_medical_engine_fnc_setLimping - * - * Public: No - */ - -params [["_unit", objNull, [objNull]], ["_isLimping", true, [false]]]; - -if (!local _unit) exitWith { - ERROR("Unit not local or null"); -}; - -_unit setVariable [QEGVAR(medical,isLimping), _isLimping, true]; - -// refresh -private _isDamaged = _unit getHitPointDamage "HitLegs" >= DAMAGED_MIN_THRESHOLD && {_unit getHitPointDamage "HitLegs" != LIMPING_MIN_DAMAGE}; - -[_unit, "Legs", _isDamaged] call FUNC(damageBodyPart); diff --git a/addons/medical_engine/functions/fnc_setStructuralDamage.sqf b/addons/medical_engine/functions/fnc_setStructuralDamage.sqf index 11821fbe25..5e3dcd7b05 100644 --- a/addons/medical_engine/functions/fnc_setStructuralDamage.sqf +++ b/addons/medical_engine/functions/fnc_setStructuralDamage.sqf @@ -24,8 +24,17 @@ if (!local _unit) exitWith { private _hitPointDamages = getAllHitPointsDamage _unit param [2, []]; +private _damageDisabled = !isDamageAllowed _unit; +if (_damageDisabled) then { + _unit allowDamage true; +}; + _unit setDamage _damage; { _unit setHitIndex [_forEachIndex, _x]; } forEach _hitPointDamages; + +if (_damageDisabled) then { + _unit allowDamage false; +}; diff --git a/addons/medical_engine/functions/fnc_setUnconsciousAnim.sqf b/addons/medical_engine/functions/fnc_setUnconsciousAnim.sqf index aa7f3f7db5..0cc61c418d 100644 --- a/addons/medical_engine/functions/fnc_setUnconsciousAnim.sqf +++ b/addons/medical_engine/functions/fnc_setUnconsciousAnim.sqf @@ -17,9 +17,10 @@ */ params [["_unit", objNull, [objNull]], ["_isUnconscious", true, [false]]]; +TRACE_2("setUnconsciousAnim",_unit,_isUnconscious); if (!local _unit) exitWith { - ERROR("Unit not local or null"); + ERROR_1("Unit %1 not local or null",_unit); }; _unit setUnconscious _isUnconscious; @@ -27,21 +28,25 @@ _unit setUnconscious _isUnconscious; if (_isUnconscious) then { // eject from static weapon if (vehicle _unit isKindOf "StaticWeapon") then { + TRACE_2("ejecting from static weapon",_unit,vehicle _unit); [_unit] call EFUNC(common,unloadPerson); }; // set animation inside vehicles if (vehicle _unit != _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 { private _awakeAnim = _unit call EFUNC(common,getAwakeAnim); + TRACE_2("inVehicle - playing awake anim",_unit,_awakeAnim); [_unit, _awakeAnim, 2] call EFUNC(common,doAnimation); } else { // and on foot + TRACE_1("onfoot - playing standard anim",_unit); [_unit, "AmovPpneMstpSnonWnonDnon"] call EFUNC(common,doAnimation); if (currentWeapon _unit == secondaryWeapon _unit && {currentWeapon _unit != ""}) then { @@ -50,9 +55,12 @@ if (_isUnconscious) then { [{ params ["_unit"]; - - if (animationState _unit == "unconscious" && {lifeState _unit != "INCAPACITATED"}) then { + TRACE_3("after delay",_unit,animationState _unit,lifeState _unit); + if (!alive _unit) exitWith {}; + // Fix unit being in locked animation with switchMove (If unit was unloaded from a vehicle, they may be in deadstate instead of unconscious) + if (((animationState _unit == "unconscious") || {animationState _unit == "deadstate"}) && {lifeState _unit != "INCAPACITATED"}) then { [_unit, "AmovPpneMstpSnonWnonDnon", 2] call EFUNC(common,doAnimation); + TRACE_1("forcing SwitchMove",animationState _unit); }; }, _unit, 0.5] call CBA_fnc_waitAndExecute; }; diff --git a/addons/medical_engine/functions/fnc_updateDamageEffects.sqf b/addons/medical_engine/functions/fnc_updateDamageEffects.sqf new file mode 100644 index 0000000000..9adfc2e855 --- /dev/null +++ b/addons/medical_engine/functions/fnc_updateDamageEffects.sqf @@ -0,0 +1,67 @@ +#include "script_component.hpp" +/* + * Author: commy2, PabstMirror + * Updates damage effects for limping and fractures + * + * Arguments: + * 0: Unit + * 1: Limping (optional, default: true) + * + * Return Value: + * None + * + * Example: + * [player] call ace_medical_engine_fnc_updateDamageEffects + * + * Public: No + */ + +params [["_unit", objNull, [objNull]]]; + +if (!local _unit) exitWith { ERROR("Unit not local or null"); }; + +private _isLimping = false; + +if (EGVAR(medical,fractures) > 0) then { + private _fractures = GET_FRACTURES(_unit); + TRACE_1("",_fractures); + if (((_fractures select 4) == 1) || {(_fractures select 5) == 1}) then { + TRACE_1("limping because of fracture",_fractures); + _isLimping = true; + }; + private _aimFracture = 0; + if ((_fractures select 2) == 1) then { _aimFracture = _aimFracture + 4; }; + if ((_fractures select 3) == 1) then { _aimFracture = _aimFracture + 4; }; + + if (EGVAR(medical,fractures) == 2) then { // the limp with a splint will still cause effects + private _isSprintBlocked = ((_fractures select 4) == -1) || {(_fractures select 5) == -1}; // block sprinting if we have a leg splint on + if (_isSprintBlocked || {!isSprintAllowed _unit}) then { // only update status effect if we need to + TRACE_1("updating status effect",_isSprintBlocked); + [_unit, "blockSprint", QEGVAR(medical,fracture), _isSprintBlocked] call EFUNC(common,statusEffect_set); + }; + if ((_fractures select 2) == 1) then { _aimFracture = _aimFracture + 2; }; + if ((_fractures select 3) == 1) then { _aimFracture = _aimFracture + 2; }; + }; + _unit setVariable [QGVAR(aimFracture), _aimFracture, false]; // local only var, used in ace_medical's postInit to set ACE_setCustomAimCoef +}; + +if (!_isLimping && {EGVAR(medical,limping) > 0}) then { + private _woundsToCheck = GET_OPEN_WOUNDS(_unit); + if (EGVAR(medical,limping) == 2) then { + _woundsToCheck = _woundsToCheck + GET_BANDAGED_WOUNDS(_unit); // do not append + }; + { + _x params ["_xClassID", "_xBodyPartN", "_xAmountOf", "", "_xDamage"]; + if ((_xBodyPartN > 3) && {_xAmountOf > 0} && {_xDamage > LIMPING_DAMAGE_THRESHOLD} && { + (EGVAR(medical_damage,woundsData) select (_xClassID / 10)) select 7}) exitWith { // select _causeLimping from woundsData + TRACE_1("limping because of wound",_x); + _isLimping = true; + }; + } forEach _woundsToCheck; +}; +_unit setVariable [QEGVAR(medical,isLimping), _isLimping, true]; + +// refresh +private _isDamaged = _unit getHitPointDamage "HitLegs" >= DAMAGED_MIN_THRESHOLD && {_unit getHitPointDamage "HitLegs" != LIMPING_MIN_DAMAGE}; + +[_unit, "Legs", _isDamaged] call FUNC(damageBodyPart); diff --git a/addons/medical_engine/script_component.hpp b/addons/medical_engine/script_component.hpp index dbe6e2a2cb..5166324b1e 100644 --- a/addons/medical_engine/script_component.hpp +++ b/addons/medical_engine/script_component.hpp @@ -1,5 +1,5 @@ #define COMPONENT medical_engine -#define COMPONENT_BEAUTIFIED Medical (Engine) +#define COMPONENT_BEAUTIFIED Medical Engine #include "\z\ace\addons\main\script_mod.hpp" // #define DEBUG_MODE_FULL diff --git a/addons/medical_engine/script_macros_medical.hpp b/addons/medical_engine/script_macros_medical.hpp index 8e38faa455..7f50866f0e 100644 --- a/addons/medical_engine/script_macros_medical.hpp +++ b/addons/medical_engine/script_macros_medical.hpp @@ -2,11 +2,17 @@ // #define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS - #define ALL_BODY_PARTS ["head", "body", "leftarm", "rightarm", "leftleg", "rightleg"] #define ALL_SELECTIONS ["head", "body", "hand_l", "hand_r", "leg_l", "leg_r"] #define ALL_HITPOINTS ["HitHead", "HitBody", "HitLeftArm", "HitRightArm", "HitLeftLeg", "HitRightLeg"] +#define HITPOINT_INDEX_HEAD 0 +#define HITPOINT_INDEX_BODY 1 +#define HITPOINT_INDEX_LARM 2 +#define HITPOINT_INDEX_RARM 3 +#define HITPOINT_INDEX_LLEG 4 +#define HITPOINT_INDEX_RLEG 5 + // Damage threshold above which fatal organ damage can occur #define HEAD_DAMAGE_THRESHOLD 1 #define ORGAN_DAMAGE_THRESHOLD 0.6 @@ -74,12 +80,15 @@ // Minimum leg damage required for limping #define LIMPING_DAMAGE_THRESHOLD 0.30 +// Minimum limb damage required for fracture +#define FRACTURE_DAMAGE_THRESHOLD 0.50 + // Minimum body part damage required for blood effect on uniform #define VISUAL_BODY_DAMAGE_THRESHOLD 0.35 // Empty wound data, used for some default return values -// [ID, classID, bodypartIndex, amountOf, bloodloss, damage, category] -#define EMPTY_WOUND [-1, -1, -1, 0, 0, 0, 0] +// [classID, bodypartIndex, amountOf, bloodloss, damage] +#define EMPTY_WOUND [-1, -1, 0, 0, 0] // Base time to bandage each wound category #define BANDAGE_TIME_S 4 @@ -92,8 +101,13 @@ #define DEFAULT_BANDAGE_REOPENING_MIN_DELAY 120 #define DEFAULT_BANDAGE_REOPENING_MAX_DELAY 200 +// Time it takes to stitch one wound +#define WOUND_STITCH_TIME 5 + #define DEFAULT_TOURNIQUET_VALUES [0,0,0,0,0,0] +#define DEFAULT_FRACTURE_VALUES [0,0,0,0,0,0] + // Triage colors, for consistency across UIs and functions #define TRIAGE_COLOR_NONE 0, 0, 0, 0.9 #define TRIAGE_COLOR_MINIMAL 0, 0.5, 0, 0.9 @@ -107,40 +121,52 @@ #define TRIAGE_TEXT_COLOR_IMMEDIATE 1, 1, 1, 1 #define TRIAGE_TEXT_COLOR_DECEASED 1, 1, 1, 1 +// Medical activity logs +#define MED_LOG_MAX_ENTRIES 8 +#define MED_LOG_VARNAME(type) (format [QEGVAR(medical,log_%1), type]) + // - Unit Variables ---------------------------------------------------- // These variables get stored in object space and used across components // Defined here for easy consistency with GETVAR/SETVAR (also a list for reference) -#define VAR_BLOOD_PRESS QEGVAR(medical,bloodPressure) -#define VAR_BLOOD_VOL QEGVAR(medical,bloodVolume) -#define VAR_WOUND_BLEEDING QEGVAR(medical,woundBleeding) -#define VAR_CRDC_ARRST QEGVAR(medical,inCardiacArrest) -#define VAR_HEART_RATE QEGVAR(medical,heartRate) -#define VAR_PAIN QEGVAR(medical,pain) -#define VAR_PAIN_SUPP QEGVAR(medical,painSuppress) -#define VAR_PERIPH_RES QEGVAR(medical,peripheralResistance) -#define VAR_UNCON "ACE_isUnconscious" +#define VAR_BLOOD_PRESS QEGVAR(medical,bloodPressure) +#define VAR_BLOOD_VOL QEGVAR(medical,bloodVolume) +#define VAR_WOUND_BLEEDING QEGVAR(medical,woundBleeding) +#define VAR_CRDC_ARRST QEGVAR(medical,inCardiacArrest) +#define VAR_HEART_RATE QEGVAR(medical,heartRate) +#define VAR_PAIN QEGVAR(medical,pain) +#define VAR_PAIN_SUPP QEGVAR(medical,painSuppress) +#define VAR_PERIPH_RES QEGVAR(medical,peripheralResistance) +#define VAR_UNCON "ACE_isUnconscious" +#define VAR_OPEN_WOUNDS QEGVAR(medical,openWounds) +#define VAR_BANDAGED_WOUNDS QEGVAR(medical,bandagedWounds) +#define VAR_STITCHED_WOUNDS QEGVAR(medical,stitchedWounds) // These variables track gradual adjustments (from medication, etc.) -#define VAR_MEDICATIONS QEGVAR(medical,medications) +#define VAR_MEDICATIONS QEGVAR(medical,medications) // These variables track the current state of status values above -#define VAR_HEMORRHAGE QEGVAR(medical,hemorrhage) -#define VAR_IN_PAIN QEGVAR(medical,inPain) -#define VAR_TOURNIQUET QEGVAR(medical,tourniquets) - +#define VAR_HEMORRHAGE QEGVAR(medical,hemorrhage) +#define VAR_IN_PAIN QEGVAR(medical,inPain) +#define VAR_TOURNIQUET QEGVAR(medical,tourniquets) +#define VAR_FRACTURES QEGVAR(medical,fractures) // - Unit Functions --------------------------------------------------- // Retrieval macros for common unit values // Defined for easy consistency and speed -#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_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]) +#define GET_SM_STATE(_unit) ([_unit, EGVAR(medical,STATE_MACHINE)] call CBA_statemachine_fnc_getCurrentState) +#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_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]) #define GET_TOURNIQUETS(unit) (unit getVariable [VAR_TOURNIQUET, DEFAULT_TOURNIQUET_VALUES]) -#define IN_CRDC_ARRST(unit) (unit getVariable [VAR_CRDC_ARRST,false]) +#define GET_FRACTURES(unit) (unit getVariable [VAR_FRACTURES, DEFAULT_FRACTURE_VALUES]) +#define IN_CRDC_ARRST(unit) (unit getVariable [VAR_CRDC_ARRST, false]) #define IS_BLEEDING(unit) (GET_WOUND_BLEEDING(unit) > 0) -#define IS_IN_PAIN(unit) (unit getVariable [VAR_IN_PAIN,false]) -#define IS_UNCONSCIOUS(unit) (unit getVariable [VAR_UNCON,false]) +#define IS_IN_PAIN(unit) (unit getVariable [VAR_IN_PAIN, false]) +#define IS_UNCONSCIOUS(unit) (unit getVariable [VAR_UNCON, false]) +#define GET_OPEN_WOUNDS(unit) (unit getVariable [VAR_OPEN_WOUNDS, []]) +#define GET_BANDAGED_WOUNDS(unit) (unit getVariable [VAR_BANDAGED_WOUNDS, []]) +#define GET_STITCHED_WOUNDS(unit) (unit getVariable [VAR_STITCHED_WOUNDS, []]) // The following function calls are defined here just for consistency #define GET_BLOOD_LOSS(unit) ([unit] call EFUNC(medical_status,getBloodLoss)) diff --git a/addons/medical_feedback/ACE_Settings.hpp b/addons/medical_feedback/ACE_Settings.hpp index 63266003e2..a42a2d0e59 100644 --- a/addons/medical_feedback/ACE_Settings.hpp +++ b/addons/medical_feedback/ACE_Settings.hpp @@ -1,4 +1,5 @@ class ACE_Settings { + /* // Not currently used anywhere class GVAR(enableScreams) { category = ECSTRING(medical,Category_Medical); @@ -7,4 +8,5 @@ class ACE_Settings { typeName = "BOOL"; value = 1; }; + */ }; diff --git a/addons/medical_feedback/CfgSounds.hpp b/addons/medical_feedback/CfgSounds.hpp index 077c32ba5e..6c390e1f7a 100644 --- a/addons/medical_feedback/CfgSounds.hpp +++ b/addons/medical_feedback/CfgSounds.hpp @@ -1,4 +1,5 @@ class CfgSounds { + // Heartbeats ------------------------------------------------------------- class ACE_heartbeat_fast_1 { name = "ACE_heartbeat_fast_1"; sound[] = {QPATHTOF(sounds\fast_1.wav), "db+1", 1}; @@ -34,4 +35,2226 @@ class CfgSounds { sound[] = {QPATHTOF(sounds\slow_2.wav), "db+1", 1}; titles[] = {}; }; + + // Fractures -------------------------------------------------------------- + class ACE_fracture_1 { + name = "ACE_fracture_1"; + sound[] = {QPATHTOF(sounds\fracture_1.wav), "db+1", 1}; + titles[] = {}; + }; + class ACE_fracture_2 { + name = "ACE_fracture_2"; + sound[] = {QPATHTOF(sounds\fracture_2.wav), "db+1", 1}; + titles[] = {}; + }; + class ACE_fracture_3 { + name = "ACE_fracture_3"; + sound[] = {QPATHTOF(sounds\fracture_3.wav), "db+1", 1}; + titles[] = {}; + }; + class ACE_fracture_4 { + name = "ACE_fracture_4"; + sound[] = {QPATHTOF(sounds\fracture_4.wav), "db+1", 1}; + titles[] = {}; + }; + + // Moans ------------------------------------------------------------------ + class ACE_moan_Male08ENG_low_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male08ENG_low_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male08ENG_low_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male08ENG_low_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male08ENG_low_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male08ENG_low_6 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Low_6", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male08ENG_low_7 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Low_7", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male08ENG_low_8 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Low_8", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male08ENG_mid_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male08ENG_mid_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male08ENG_mid_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male08ENG_mid_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male08ENG_mid_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male08ENG_mid_6 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Mid_6", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male08ENG_mid_7 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Mid_7", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male08ENG_mid_8 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Mid_8", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male08ENG_high_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male08ENG_high_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male08ENG_high_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male08ENG_high_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male08ENG_high_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Max_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male08ENG_high_6 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Max_6", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male08ENG_high_7 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Max_7", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male08ENG_high_8 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Max_8", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06ENG_low_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06ENG_low_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06ENG_low_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06ENG_low_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06ENG_low_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06ENG_low_6 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Low_6", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06ENG_low_7 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Low_7", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06ENG_low_8 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Low_8", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06ENG_mid_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06ENG_mid_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06ENG_mid_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06ENG_mid_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06ENG_mid_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06ENG_mid_6 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Mid_6", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06ENG_mid_7 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Mid_7", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06ENG_mid_8 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Mid_8", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06ENG_high_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06ENG_high_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06ENG_high_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06ENG_high_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06ENG_high_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Max_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06ENG_high_6 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Max_6", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06ENG_high_7 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Max_7", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06ENG_high_8 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Max_8", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male09ENG_low_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P03\Soundinjured_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male09ENG_low_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P03\Soundinjured_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male09ENG_low_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P03\Soundinjured_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male09ENG_low_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P03\Soundinjured_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male09ENG_low_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P03\Soundinjured_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male09ENG_mid_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P03\Soundinjured_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male09ENG_mid_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P03\Soundinjured_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male09ENG_mid_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P03\Soundinjured_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male09ENG_mid_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P03\Soundinjured_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male09ENG_mid_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P03\Soundinjured_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male09ENG_high_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P03\Soundinjured_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male09ENG_high_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P03\Soundinjured_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male09ENG_high_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P03\Soundinjured_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male09ENG_high_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P03\Soundinjured_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male07ENG_low_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P04\Soundinjured_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male07ENG_low_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P04\Soundinjured_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male07ENG_low_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P04\Soundinjured_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male07ENG_low_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P04\Soundinjured_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male07ENG_low_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P04\Soundinjured_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male07ENG_mid_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P04\Soundinjured_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male07ENG_mid_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P04\Soundinjured_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male07ENG_mid_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P04\Soundinjured_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male07ENG_mid_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P04\Soundinjured_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male07ENG_mid_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P04\Soundinjured_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male07ENG_high_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P04\Soundinjured_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male07ENG_high_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P04\Soundinjured_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male07ENG_high_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P04\Soundinjured_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male07ENG_high_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P04\Soundinjured_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male07ENG_high_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P04\Soundinjured_Max_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03GRE_low_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P05\Soundinjured_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03GRE_low_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P05\Soundinjured_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03GRE_low_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P05\Soundinjured_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03GRE_low_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P05\Soundinjured_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03GRE_low_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P05\Soundinjured_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03GRE_mid_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P05\Soundinjured_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03GRE_mid_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P05\Soundinjured_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03GRE_mid_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P05\Soundinjured_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03GRE_mid_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P05\Soundinjured_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03GRE_mid_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P05\Soundinjured_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03GRE_high_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P05\Soundinjured_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03GRE_high_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P05\Soundinjured_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03GRE_high_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P05\Soundinjured_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03GRE_high_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P05\Soundinjured_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03GRE_high_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P05\Soundinjured_Max_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02ENGB_low_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P06\Soundinjured_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02ENGB_low_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P06\Soundinjured_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02ENGB_low_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P06\Soundinjured_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02ENGB_low_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P06\Soundinjured_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02ENGB_low_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P06\Soundinjured_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02ENGB_mid_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P06\Soundinjured_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02ENGB_mid_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P06\Soundinjured_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02ENGB_mid_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P06\Soundinjured_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02ENGB_mid_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P06\Soundinjured_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02ENGB_mid_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P06\Soundinjured_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02ENGB_high_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P06\Soundinjured_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02ENGB_high_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P06\Soundinjured_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02ENGB_high_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P06\Soundinjured_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02ENGB_high_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P06\Soundinjured_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02ENGB_high_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P06\Soundinjured_Max_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male01ENGB_low_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P07\Soundinjured_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male01ENGB_low_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P07\Soundinjured_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male01ENGB_low_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P07\Soundinjured_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male01ENGB_low_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P07\Soundinjured_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male01ENGB_low_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P07\Soundinjured_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male01ENGB_mid_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P07\Soundinjured_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male01ENGB_mid_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P07\Soundinjured_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male01ENGB_mid_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P07\Soundinjured_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male01ENGB_mid_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P07\Soundinjured_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male01ENGB_mid_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P07\Soundinjured_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male01ENGB_high_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P07\Soundinjured_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male01ENGB_high_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P07\Soundinjured_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male01ENGB_high_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P07\Soundinjured_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male01ENGB_high_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P07\Soundinjured_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male01ENGB_high_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P07\Soundinjured_Max_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male01GRE_low_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P08\Soundinjured_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male01GRE_low_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P08\Soundinjured_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male01GRE_low_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P08\Soundinjured_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male01GRE_low_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P08\Soundinjured_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male01GRE_low_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P08\Soundinjured_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male01GRE_mid_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P08\Soundinjured_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male01GRE_mid_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P08\Soundinjured_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male01GRE_mid_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P08\Soundinjured_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male01GRE_mid_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P08\Soundinjured_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male01GRE_mid_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P08\Soundinjured_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male01GRE_high_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P08\Soundinjured_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male01GRE_high_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P08\Soundinjured_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male01GRE_high_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P08\Soundinjured_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male01GRE_high_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P08\Soundinjured_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male01GRE_high_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P08\Soundinjured_Max_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02ENG_low_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P09\Soundinjured_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02ENG_low_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P09\Soundinjured_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02ENG_low_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P09\Soundinjured_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02ENG_low_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P09\Soundinjured_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02ENG_low_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P09\Soundinjured_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02ENG_mid_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P09\Soundinjured_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02ENG_mid_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P09\Soundinjured_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02ENG_mid_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P09\Soundinjured_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02ENG_mid_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P09\Soundinjured_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02ENG_mid_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P09\Soundinjured_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02ENG_high_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P09\Soundinjured_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02ENG_high_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P09\Soundinjured_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02ENG_high_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P09\Soundinjured_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02ENG_high_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P09\Soundinjured_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02ENG_high_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P09\Soundinjured_Max_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02GRE_low_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P10\Soundinjured_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02GRE_low_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P10\Soundinjured_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02GRE_low_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P10\Soundinjured_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02GRE_low_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P10\Soundinjured_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02GRE_low_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P10\Soundinjured_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02GRE_mid_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P10\Soundinjured_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02GRE_mid_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P10\Soundinjured_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02GRE_mid_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P10\Soundinjured_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02GRE_mid_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P10\Soundinjured_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02GRE_mid_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P10\Soundinjured_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02GRE_high_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P10\Soundinjured_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02GRE_high_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P10\Soundinjured_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02GRE_high_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P10\Soundinjured_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02GRE_high_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P10\Soundinjured_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male02GRE_high_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P10\Soundinjured_Max_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03ENG_low_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P11\Soundinjured_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03ENG_low_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P11\Soundinjured_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03ENG_low_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P11\Soundinjured_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03ENG_low_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P11\Soundinjured_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03ENG_low_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P11\Soundinjured_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03ENG_mid_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P11\Soundinjured_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03ENG_mid_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P11\Soundinjured_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03ENG_mid_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P11\Soundinjured_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03ENG_mid_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P11\Soundinjured_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03ENG_mid_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P11\Soundinjured_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03ENG_high_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P11\Soundinjured_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03ENG_high_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P11\Soundinjured_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03ENG_high_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P11\Soundinjured_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03ENG_high_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P11\Soundinjured_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03ENG_high_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P11\Soundinjured_Max_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03ENGB_low_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P12\Soundinjured_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03ENGB_low_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P12\Soundinjured_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03ENGB_low_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P12\Soundinjured_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03ENGB_low_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P12\Soundinjured_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03ENGB_low_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P12\Soundinjured_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03ENGB_mid_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P12\Soundinjured_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03ENGB_mid_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P12\Soundinjured_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03ENGB_mid_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P12\Soundinjured_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03ENGB_mid_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P12\Soundinjured_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03ENGB_mid_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P12\Soundinjured_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03ENGB_high_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P12\Soundinjured_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03ENGB_high_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P12\Soundinjured_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03ENGB_high_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P12\Soundinjured_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03ENGB_high_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P12\Soundinjured_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male03ENGB_high_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P12\Soundinjured_Max_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male04ENG_low_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P13\Soundinjured_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male04ENG_low_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P13\Soundinjured_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male04ENG_low_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P13\Soundinjured_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male04ENG_low_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P13\Soundinjured_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male04ENG_low_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P13\Soundinjured_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male04ENG_mid_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P13\Soundinjured_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male04ENG_mid_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P13\Soundinjured_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male04ENG_mid_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P13\Soundinjured_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male04ENG_mid_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P13\Soundinjured_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male04ENG_mid_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P13\Soundinjured_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male04ENG_high_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P13\Soundinjured_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male04ENG_high_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P13\Soundinjured_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male04ENG_high_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P13\Soundinjured_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male04ENG_high_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P13\Soundinjured_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male04ENG_high_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P13\Soundinjured_Max_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05GRE_low_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P14\Soundinjured_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05GRE_low_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P14\Soundinjured_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05GRE_low_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P14\Soundinjured_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05GRE_low_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P14\Soundinjured_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05GRE_low_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P14\Soundinjured_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05GRE_mid_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P14\Soundinjured_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05GRE_mid_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P14\Soundinjured_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05GRE_mid_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P14\Soundinjured_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05GRE_mid_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P14\Soundinjured_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05GRE_mid_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P14\Soundinjured_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05GRE_high_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P14\Soundinjured_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05GRE_high_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P14\Soundinjured_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05GRE_high_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P14\Soundinjured_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05GRE_high_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P14\Soundinjured_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05GRE_high_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P14\Soundinjured_Max_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06GRE_low_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P15\Soundinjured_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06GRE_low_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P15\Soundinjured_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06GRE_low_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P15\Soundinjured_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06GRE_low_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P15\Soundinjured_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06GRE_low_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P15\Soundinjured_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06GRE_mid_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P15\Soundinjured_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06GRE_mid_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P15\Soundinjured_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06GRE_mid_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P15\Soundinjured_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06GRE_mid_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P15\Soundinjured_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06GRE_mid_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P15\Soundinjured_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06GRE_high_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P15\Soundinjured_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06GRE_high_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P15\Soundinjured_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06GRE_high_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P15\Soundinjured_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06GRE_high_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P15\Soundinjured_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male06GRE_high_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P15\Soundinjured_Max_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male04GRE_low_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P16\Soundinjured_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male04GRE_low_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P16\Soundinjured_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male04GRE_low_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P16\Soundinjured_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male04GRE_low_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P16\Soundinjured_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male04GRE_low_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P16\Soundinjured_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male04GRE_mid_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P16\Soundinjured_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male04GRE_mid_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P16\Soundinjured_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male04GRE_mid_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P16\Soundinjured_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male04GRE_mid_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P16\Soundinjured_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male04GRE_mid_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P16\Soundinjured_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male04GRE_high_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P16\Soundinjured_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male04GRE_high_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P16\Soundinjured_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male04GRE_high_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P16\Soundinjured_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male04GRE_high_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P16\Soundinjured_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male04GRE_high_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P16\Soundinjured_Max_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05ENGB_low_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P17\Soundinjured_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05ENGB_low_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P17\Soundinjured_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05ENGB_low_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P17\Soundinjured_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05ENGB_low_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P17\Soundinjured_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05ENGB_low_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P17\Soundinjured_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05ENGB_mid_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P17\Soundinjured_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05ENGB_mid_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P17\Soundinjured_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05ENGB_mid_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P17\Soundinjured_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05ENGB_mid_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P17\Soundinjured_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05ENGB_mid_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P17\Soundinjured_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05ENGB_high_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P17\Soundinjured_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05ENGB_high_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P17\Soundinjured_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05ENGB_high_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P17\Soundinjured_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05ENGB_high_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P17\Soundinjured_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05ENGB_high_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P17\Soundinjured_Max_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05ENG_low_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P18\Soundinjured_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05ENG_low_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P18\Soundinjured_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05ENG_low_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P18\Soundinjured_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05ENG_low_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P18\Soundinjured_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05ENG_low_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P18\Soundinjured_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05ENG_mid_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P18\Soundinjured_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05ENG_mid_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P18\Soundinjured_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05ENG_mid_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P18\Soundinjured_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05ENG_mid_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P18\Soundinjured_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05ENG_mid_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P18\Soundinjured_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05ENG_high_1 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P18\Soundinjured_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05ENG_high_2 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P18\Soundinjured_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05ENG_high_3 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P18\Soundinjured_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05ENG_high_4 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P18\Soundinjured_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_moan_Male05ENG_high_5 { + sound[] = {"A3\Sounds_F\characters\human-sfx\P18\Soundinjured_Max_5", "db+1", 1}; + titles[] = {}; + }; + + // Screams ---------------------------------------------------------------- + class ACE_hit_Male08ENG_low_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P01\Low_hit_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male08ENG_low_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P01\Low_hit_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male08ENG_low_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P01\Low_hit_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male08ENG_low_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P01\Low_hit_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male08ENG_low_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P01\Low_hit_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male08ENG_mid_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P01\Mid_hit_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male08ENG_mid_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P01\Mid_hit_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male08ENG_mid_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P01\Mid_hit_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male08ENG_mid_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P01\Mid_hit_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male08ENG_high_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P01\Max_hit_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male08ENG_high_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P01\Max_hit_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male08ENG_high_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P01\Max_hit_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male08ENG_high_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P01\Max_hit_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male08ENG_high_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P01\Max_hit_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male06ENG_low_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P02\Low_hit_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male06ENG_low_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P02\Low_hit_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male06ENG_low_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P02\Low_hit_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male06ENG_low_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P02\Low_hit_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male06ENG_low_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P02\Low_hit_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male06ENG_low_6 { + sound[] = {"A3\sounds_f\characters\human-sfx\P02\Low_hit_6", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male06ENG_mid_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P02\Mid_hit_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male06ENG_mid_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P02\Mid_hit_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male06ENG_mid_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P02\Mid_hit_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male06ENG_mid_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P02\Mid_hit_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male06ENG_high_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P02\Max_hit_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male06ENG_high_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P02\Max_hit_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male06ENG_high_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P02\Max_hit_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male06ENG_high_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P02\Max_hit_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male09ENG_low_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P03\Hit_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male09ENG_low_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P03\Hit_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male09ENG_low_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P03\Hit_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male09ENG_mid_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P03\Hit_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male09ENG_mid_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P03\Hit_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male09ENG_mid_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P03\Hit_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male09ENG_high_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P03\Hit_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male09ENG_high_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P03\Hit_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male09ENG_high_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P03\Hit_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male07ENG_low_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P04\Hit_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male07ENG_low_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P04\Hit_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male07ENG_low_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P04\Hit_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male07ENG_low_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P04\Hit_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male07ENG_low_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P04\Hit_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male07ENG_mid_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P04\Hit_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male07ENG_mid_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P04\Hit_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male07ENG_mid_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P04\Hit_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male07ENG_mid_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P04\Hit_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male07ENG_mid_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P04\Hit_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male07ENG_high_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P04\Hit_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male07ENG_high_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P04\Hit_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male07ENG_high_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P04\Hit_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male07ENG_high_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P04\Hit_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male07ENG_high_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P04\Hit_Max_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03GRE_low_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P05\Hit_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03GRE_low_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P05\Hit_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03GRE_low_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P05\Hit_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03GRE_low_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P05\Hit_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03GRE_low_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P05\Hit_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03GRE_mid_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P05\Hit_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03GRE_mid_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P05\Hit_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03GRE_mid_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P05\Hit_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03GRE_mid_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P05\Hit_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03GRE_mid_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P05\Hit_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03GRE_high_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P05\Hit_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03GRE_high_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P05\Hit_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03GRE_high_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P05\Hit_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03GRE_high_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P05\Hit_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03GRE_high_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P05\Hit_Max_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02ENGB_low_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P06\Hit_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02ENGB_low_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P06\Hit_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02ENGB_low_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P06\Hit_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02ENGB_low_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P06\Hit_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02ENGB_low_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P06\Hit_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02ENGB_mid_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P06\Hit_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02ENGB_mid_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P06\Hit_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02ENGB_mid_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P06\Hit_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02ENGB_mid_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P06\Hit_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02ENGB_mid_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P06\Hit_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02ENGB_high_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P06\Hit_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02ENGB_high_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P06\Hit_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02ENGB_high_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P06\Hit_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02ENGB_high_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P06\Hit_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02ENGB_high_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P06\Hit_Max_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male01ENGB_low_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P07\Hit_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male01ENGB_low_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P07\Hit_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male01ENGB_low_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P07\Hit_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male01ENGB_low_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P07\Hit_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male01ENGB_low_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P07\Hit_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male01ENGB_mid_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P07\Hit_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male01ENGB_mid_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P07\Hit_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male01ENGB_mid_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P07\Hit_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male01ENGB_mid_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P07\Hit_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male01ENGB_mid_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P07\Hit_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male01ENGB_high_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P07\Hit_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male01ENGB_high_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P07\Hit_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male01ENGB_high_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P07\Hit_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male01ENGB_high_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P07\Hit_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male01ENGB_high_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P07\Hit_Max_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male01GRE_low_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P08\Hit_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male01GRE_low_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P08\Hit_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male01GRE_low_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P08\Hit_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male01GRE_low_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P08\Hit_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male01GRE_low_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P08\Hit_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male01GRE_mid_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P08\Hit_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male01GRE_mid_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P08\Hit_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male01GRE_mid_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P08\Hit_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male01GRE_mid_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P08\Hit_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male01GRE_mid_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P08\Hit_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male01GRE_high_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P08\Hit_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male01GRE_high_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P08\Hit_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male01GRE_high_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P08\Hit_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male01GRE_high_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P08\Hit_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male01GRE_high_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P08\Hit_Max_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02ENG_low_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P09\Hit_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02ENG_low_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P09\Hit_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02ENG_low_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P09\Hit_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02ENG_low_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P09\Hit_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02ENG_low_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P09\Hit_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02ENG_mid_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P09\Hit_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02ENG_mid_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P09\Hit_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02ENG_mid_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P09\Hit_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02ENG_mid_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P09\Hit_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02ENG_mid_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P09\Hit_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02ENG_high_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P09\Hit_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02ENG_high_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P09\Hit_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02ENG_high_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P09\Hit_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02ENG_high_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P09\Hit_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02ENG_high_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P09\Hit_Max_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02GRE_low_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P10\Hit_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02GRE_low_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P10\Hit_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02GRE_low_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P10\Hit_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02GRE_low_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P10\Hit_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02GRE_low_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P10\Hit_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02GRE_mid_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P10\Hit_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02GRE_mid_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P10\Hit_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02GRE_mid_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P10\Hit_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02GRE_mid_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P10\Hit_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02GRE_mid_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P10\Hit_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02GRE_high_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P10\Hit_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02GRE_high_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P10\Hit_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02GRE_high_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P10\Hit_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02GRE_high_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P10\Hit_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male02GRE_high_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P10\Hit_Max_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03ENG_low_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P11\Hit_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03ENG_low_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P11\Hit_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03ENG_low_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P11\Hit_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03ENG_low_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P11\Hit_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03ENG_low_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P11\Hit_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03ENG_mid_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P11\Hit_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03ENG_mid_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P11\Hit_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03ENG_mid_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P11\Hit_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03ENG_mid_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P11\Hit_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03ENG_mid_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P11\Hit_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03ENG_high_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P11\Hit_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03ENG_high_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P11\Hit_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03ENG_high_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P11\Hit_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03ENG_high_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P11\Hit_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03ENG_high_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P11\Hit_Max_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03ENGB_low_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P12\Hit_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03ENGB_low_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P12\Hit_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03ENGB_low_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P12\Hit_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03ENGB_low_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P12\Hit_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03ENGB_low_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P12\Hit_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03ENGB_mid_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P12\Hit_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03ENGB_mid_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P12\Hit_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03ENGB_mid_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P12\Hit_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03ENGB_mid_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P12\Hit_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03ENGB_mid_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P12\Hit_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03ENGB_high_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P12\Hit_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03ENGB_high_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P12\Hit_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03ENGB_high_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P12\Hit_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03ENGB_high_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P12\Hit_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male03ENGB_high_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P12\Hit_Max_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male04ENG_low_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P13\Hit_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male04ENG_low_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P13\Hit_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male04ENG_low_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P13\Hit_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male04ENG_low_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P13\Hit_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male04ENG_low_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P13\Hit_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male04ENG_mid_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P13\Hit_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male04ENG_mid_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P13\Hit_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male04ENG_mid_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P13\Hit_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male04ENG_mid_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P13\Hit_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male04ENG_mid_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P13\Hit_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male04ENG_high_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P13\Hit_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male04ENG_high_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P13\Hit_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male04ENG_high_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P13\Hit_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male04ENG_high_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P13\Hit_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male04ENG_high_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P13\Hit_Max_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05GRE_low_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P14\Hit_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05GRE_low_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P14\Hit_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05GRE_low_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P14\Hit_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05GRE_low_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P14\Hit_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05GRE_low_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P14\Hit_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05GRE_mid_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P14\Hit_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05GRE_mid_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P14\Hit_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05GRE_mid_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P14\Hit_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05GRE_mid_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P14\Hit_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05GRE_mid_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P14\Hit_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05GRE_high_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P14\Hit_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05GRE_high_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P14\Hit_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05GRE_high_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P14\Hit_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05GRE_high_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P14\Hit_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05GRE_high_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P14\Hit_Max_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male06GRE_low_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P15\Hit_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male06GRE_low_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P15\Hit_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male06GRE_low_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P15\Hit_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male06GRE_low_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P15\Hit_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male06GRE_low_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P15\Hit_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male06GRE_mid_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P15\Hit_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male06GRE_mid_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P15\Hit_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male06GRE_mid_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P15\Hit_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male06GRE_mid_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P15\Hit_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male06GRE_mid_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P15\Hit_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male06GRE_high_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P15\Hit_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male06GRE_high_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P15\Hit_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male06GRE_high_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P15\Hit_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male06GRE_high_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P15\Hit_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male06GRE_high_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P15\Hit_Max_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male04GRE_low_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P16\Hit_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male04GRE_low_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P16\Hit_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male04GRE_low_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P16\Hit_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male04GRE_low_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P16\Hit_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male04GRE_low_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P16\Hit_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male04GRE_mid_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P16\Hit_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male04GRE_mid_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P16\Hit_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male04GRE_mid_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P16\Hit_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male04GRE_mid_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P16\Hit_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male04GRE_mid_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P16\Hit_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male04GRE_high_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P16\Hit_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male04GRE_high_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P16\Hit_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male04GRE_high_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P16\Hit_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male04GRE_high_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P16\Hit_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male04GRE_high_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P16\Hit_Max_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05ENGB_low_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P17\Hit_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05ENGB_low_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P17\Hit_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05ENGB_low_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P17\Hit_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05ENGB_low_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P17\Hit_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05ENGB_low_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P17\Hit_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05ENGB_mid_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P17\Hit_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05ENGB_mid_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P17\Hit_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05ENGB_mid_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P17\Hit_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05ENGB_mid_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P17\Hit_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05ENGB_mid_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P17\Hit_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05ENGB_high_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P17\Hit_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05ENGB_high_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P17\Hit_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05ENGB_high_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P17\Hit_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05ENGB_high_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P17\Hit_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05ENGB_high_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P17\Hit_Max_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05ENG_low_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P18\Hit_Low_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05ENG_low_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P18\Hit_Low_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05ENG_low_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P18\Hit_Low_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05ENG_low_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P18\Hit_Low_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05ENG_low_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P18\Hit_Low_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05ENG_mid_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P18\Hit_Mid_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05ENG_mid_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P18\Hit_Mid_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05ENG_mid_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P18\Hit_Mid_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05ENG_mid_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P18\Hit_Mid_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05ENG_mid_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P18\Hit_Mid_5", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05ENG_high_1 { + sound[] = {"A3\sounds_f\characters\human-sfx\P18\Hit_Max_1", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05ENG_high_2 { + sound[] = {"A3\sounds_f\characters\human-sfx\P18\Hit_Max_2", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05ENG_high_3 { + sound[] = {"A3\sounds_f\characters\human-sfx\P18\Hit_Max_3", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05ENG_high_4 { + sound[] = {"A3\sounds_f\characters\human-sfx\P18\Hit_Max_4", "db+1", 1}; + titles[] = {}; + }; + class ACE_hit_Male05ENG_high_5 { + sound[] = {"A3\sounds_f\characters\human-sfx\P18\Hit_Max_5", "db+1", 1}; + titles[] = {}; + }; }; diff --git a/addons/medical_feedback/XEH_postInit.sqf b/addons/medical_feedback/XEH_postInit.sqf index faa826a534..2f18bc1583 100644 --- a/addons/medical_feedback/XEH_postInit.sqf +++ b/addons/medical_feedback/XEH_postInit.sqf @@ -3,6 +3,10 @@ [QEGVAR(medical,injured), { params ["_unit", "_painLevel"]; [_unit, "hit", PAIN_TO_SCREAM(_painLevel)] call FUNC(playInjuredSound); + + if (hasInterface && {_unit == ace_player}) then { + [true] call FUNC(handleEffects); + }; }] call CBA_fnc_addEventHandler; [QEGVAR(medical,moan), { @@ -12,16 +16,32 @@ if (!hasInterface) exitWith {}; +[QEGVAR(medical,fracture), { + params ["_unit"]; + if (_unit == ACE_player) then { + playSound SND_FRACTURE; + }; +}] call CBA_fnc_addEventHandler; + GVAR(nextFadeIn) = 0; GVAR(heartBeatEffectRunning) = false; +GVAR(lastHeartBeatSound) = 0; +GVAR(bloodTickCounter) = 0; [false] call FUNC(initEffects); -[LINKFUNC(handleEffects), 1, []] call CBA_fnc_addPerFrameHandler; +[true] call FUNC(handleEffects); +[FUNC(handleEffects), 1, false] call CBA_fnc_addPerFrameHandler; ["ace_unconscious", { params ["_unit", "_unconscious"]; if (_unit != ACE_player) exitWith {}; + TRACE_1("player unconscious eh",_unconscious); + + if (_unconscious && {cameraView == "GUNNER"} && {(vehicle _unit) != _unit} && {cameraOn == vehicle _unit}) then { + TRACE_2("exiting gunner view",cameraOn,cameraView); + ACE_player switchCamera "INTERNAL"; + }; // Toggle unconscious player's ability to talk in radio addons if (["task_force_radio"] call EFUNC(common,isModLoaded)) then { @@ -31,10 +51,11 @@ GVAR(heartBeatEffectRunning) = false; if (["acre_main"] call EFUNC(common,isModLoaded)) then { _unit setVariable ["acre_sys_core_isDisabled", _unconscious, true]; }; + // Greatly reduce player's hearing ability while unconscious (affects radio addons) [QUOTE(ADDON), VOL_UNCONSCIOUS, _unconscious] call EFUNC(common,setHearingCapability); - [_unconscious, 1] call FUNC(effectUnconscious); + [true] call FUNC(handleEffects); ["unconscious", _unconscious] call EFUNC(common,setDisableUserInputStatus); }] call CBA_fnc_addEventHandler; @@ -56,8 +77,7 @@ GVAR(heartBeatEffectRunning) = false; // Update effects to match new unit's current status (this also handles respawn) ["unit", { params ["_new"]; - - private _status = _new getVariable ["ace_unconscious", false]; + private _status = IS_UNCONSCIOUS(_new); if (["task_force_radio"] call EFUNC(common,isModLoaded)) then { _new setVariable ["tf_voiceVolume", [1, 0] select _status, true]; @@ -67,10 +87,31 @@ GVAR(heartBeatEffectRunning) = false; _new setVariable ["acre_sys_core_isDisabled", _status, true]; }; [QUOTE(ADDON), VOL_UNCONSCIOUS, _status] call EFUNC(common,setHearingCapability); - [_status, 0] call FUNC(effectUnconscious); + [true] call FUNC(handleEffects); ["unconscious", _status] call EFUNC(common,setDisableUserInputStatus); }] call CBA_fnc_addPlayerEventHandler; +// Forced say3D +[QGVAR(forceSay3D), { + params ["_unit", "_sound", "_distance"]; + + if (ACE_player distance _unit > _distance) exitWith {}; + + if (vehicle _unit == _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"]; + _dummy say3D [_sound, _distance, 1, false]; + + [{ + detach _this; + deleteVehicle _this; + }, _dummy, 5] call CBA_fnc_waitAndExecute; + } else { + // Fallback: attachTo doesn't work within vehicles + _unit say3D [_sound, _distance, 1, false]; + }; +}] call CBA_fnc_addEventHandler; // Kill vanilla bleeding feedback effects. #ifdef DISABLE_VANILLA_DAMAGE_EFFECTS diff --git a/addons/medical_feedback/XEH_preInit.sqf b/addons/medical_feedback/XEH_preInit.sqf index d064e3d1ef..9361d05015 100644 --- a/addons/medical_feedback/XEH_preInit.sqf +++ b/addons/medical_feedback/XEH_preInit.sqf @@ -8,743 +8,4 @@ PREP_RECOMPILE_END; #include "initSettings.sqf" -GVAR(lastHeartBeatSound) = 0; - -// HitScream -GVAR(HitScreamNamespace) = [] call CBA_fnc_createNamespace; -GVAR(HitScreamNamespace) setVariable ["#default", "Male08ENG"]; - -GVAR(HitScreamNamespace) setVariable ["Male08ENG", [[ - ["A3\sounds_f\characters\human-sfx\P01\Low_hit_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P01\Low_hit_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P01\Low_hit_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P01\Low_hit_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P01\Low_hit_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P01\Mid_hit_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P01\Mid_hit_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P01\Mid_hit_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P01\Mid_hit_4",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P01\Max_hit_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P01\Max_hit_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P01\Max_hit_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P01\Max_hit_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P01\Max_hit_5",3.1622777,1,80] -]]]; - -GVAR(HitScreamNamespace) setVariable ["Male06ENG", [[ - ["A3\sounds_f\characters\human-sfx\P02\Low_hit_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P02\Low_hit_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P02\Low_hit_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P02\Low_hit_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P02\Low_hit_5",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P02\Low_hit_6",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P02\Mid_hit_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P02\Mid_hit_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P02\Mid_hit_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P02\Mid_hit_4",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P02\Max_hit_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P02\Max_hit_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P02\Max_hit_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P02\Max_hit_4",3.1622777,1,80] -]]]; - -GVAR(HitScreamNamespace) setVariable ["Male09ENG", [[ - ["A3\sounds_f\characters\human-sfx\P03\Hit_Low_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P03\Hit_Low_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P03\Hit_Low_3",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P03\Hit_Mid_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P03\Hit_Mid_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P03\Hit_Mid_3",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P03\Hit_Max_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P03\Hit_Max_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P03\Hit_Max_3",3.1622777,1,80] -]]]; - -GVAR(HitScreamNamespace) setVariable ["Male07ENG", [[ - ["A3\sounds_f\characters\human-sfx\P04\Hit_Low_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P04\Hit_Low_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P04\Hit_Low_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P04\Hit_Low_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P04\Hit_Low_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P04\Hit_Mid_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P04\Hit_Mid_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P04\Hit_Mid_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P04\Hit_Mid_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P04\Hit_Mid_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P04\Hit_Max_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P04\Hit_Max_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P04\Hit_Max_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P04\Hit_Max_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P04\Hit_Max_5",3.1622777,1,80] -]]]; - -GVAR(HitScreamNamespace) setVariable ["Male03GRE", [[ - ["A3\sounds_f\characters\human-sfx\P05\Hit_Low_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P05\Hit_Low_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P05\Hit_Low_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P05\Hit_Low_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P05\Hit_Low_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P05\Hit_Mid_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P05\Hit_Mid_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P05\Hit_Mid_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P05\Hit_Mid_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P05\Hit_Mid_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P05\Hit_Max_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P05\Hit_Max_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P05\Hit_Max_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P05\Hit_Max_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P05\Hit_Max_5",3.1622777,1,80] -]]]; - -GVAR(HitScreamNamespace) setVariable ["Male02ENGB", [[ - ["A3\sounds_f\characters\human-sfx\P06\Hit_Low_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P06\Hit_Low_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P06\Hit_Low_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P06\Hit_Low_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P06\Hit_Low_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P06\Hit_Mid_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P06\Hit_Mid_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P06\Hit_Mid_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P06\Hit_Mid_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P06\Hit_Mid_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P06\Hit_Max_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P06\Hit_Max_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P06\Hit_Max_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P06\Hit_Max_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P06\Hit_Max_5",3.1622777,1,80] -]]]; - -GVAR(HitScreamNamespace) setVariable ["Male01ENGB", [[ - ["A3\sounds_f\characters\human-sfx\P07\Hit_Low_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P07\Hit_Low_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P07\Hit_Low_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P07\Hit_Low_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P07\Hit_Low_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P07\Hit_Mid_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P07\Hit_Mid_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P07\Hit_Mid_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P07\Hit_Mid_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P07\Hit_Mid_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P07\Hit_Max_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P07\Hit_Max_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P07\Hit_Max_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P07\Hit_Max_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P07\Hit_Max_5",3.1622777,1,80] -]]]; - -GVAR(HitScreamNamespace) setVariable ["Male01GRE", [[ - ["A3\sounds_f\characters\human-sfx\P08\Hit_Low_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P08\Hit_Low_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P08\Hit_Low_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P08\Hit_Low_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P08\Hit_Low_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P08\Hit_Mid_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P08\Hit_Mid_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P08\Hit_Mid_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P08\Hit_Mid_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P08\Hit_Mid_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P08\Hit_Max_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P08\Hit_Max_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P08\Hit_Max_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P08\Hit_Max_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P08\Hit_Max_5",3.1622777,1,80] -]]]; - -GVAR(HitScreamNamespace) setVariable ["Male02ENG", [[ - ["A3\sounds_f\characters\human-sfx\P09\Hit_Low_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P09\Hit_Low_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P09\Hit_Low_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P09\Hit_Low_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P09\Hit_Low_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P09\Hit_Mid_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P09\Hit_Mid_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P09\Hit_Mid_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P09\Hit_Mid_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P09\Hit_Mid_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P09\Hit_Max_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P09\Hit_Max_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P09\Hit_Max_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P09\Hit_Max_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P09\Hit_Max_5",3.1622777,1,80] -]]]; - -GVAR(HitScreamNamespace) setVariable ["Male02GRE", [[ - ["A3\sounds_f\characters\human-sfx\P10\Hit_Low_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P10\Hit_Low_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P10\Hit_Low_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P10\Hit_Low_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P10\Hit_Low_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P10\Hit_Mid_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P10\Hit_Mid_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P10\Hit_Mid_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P10\Hit_Mid_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P10\Hit_Mid_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P10\Hit_Max_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P10\Hit_Max_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P10\Hit_Max_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P10\Hit_Max_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P10\Hit_Max_5",3.1622777,1,80] -]]]; - -GVAR(HitScreamNamespace) setVariable ["Male03ENG", [[ - ["A3\sounds_f\characters\human-sfx\P11\Hit_Low_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P11\Hit_Low_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P11\Hit_Low_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P11\Hit_Low_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P11\Hit_Low_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P11\Hit_Mid_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P11\Hit_Mid_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P11\Hit_Mid_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P11\Hit_Mid_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P11\Hit_Mid_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P11\Hit_Max_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P11\Hit_Max_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P11\Hit_Max_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P11\Hit_Max_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P11\Hit_Max_5",3.1622777,1,80] -]]]; - -GVAR(HitScreamNamespace) setVariable ["Male03ENGB", [[ - ["A3\sounds_f\characters\human-sfx\P12\Hit_Low_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P12\Hit_Low_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P12\Hit_Low_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P12\Hit_Low_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P12\Hit_Low_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P12\Hit_Mid_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P12\Hit_Mid_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P12\Hit_Mid_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P12\Hit_Mid_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P12\Hit_Mid_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P12\Hit_Max_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P12\Hit_Max_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P12\Hit_Max_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P12\Hit_Max_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P12\Hit_Max_5",3.1622777,1,80] -]]]; - -GVAR(HitScreamNamespace) setVariable ["Male04ENG", [[ - ["A3\sounds_f\characters\human-sfx\P13\Hit_Low_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P13\Hit_Low_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P13\Hit_Low_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P13\Hit_Low_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P13\Hit_Low_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P13\Hit_Mid_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P13\Hit_Mid_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P13\Hit_Mid_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P13\Hit_Mid_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P13\Hit_Mid_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P13\Hit_Max_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P13\Hit_Max_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P13\Hit_Max_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P13\Hit_Max_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P13\Hit_Max_5",3.1622777,1,80] -]]]; - -GVAR(HitScreamNamespace) setVariable ["Male05GRE", [[ - ["A3\sounds_f\characters\human-sfx\P14\Hit_Low_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P14\Hit_Low_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P14\Hit_Low_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P14\Hit_Low_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P14\Hit_Low_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P14\Hit_Mid_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P14\Hit_Mid_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P14\Hit_Mid_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P14\Hit_Mid_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P14\Hit_Mid_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P14\Hit_Max_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P14\Hit_Max_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P14\Hit_Max_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P14\Hit_Max_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P14\Hit_Max_5",3.1622777,1,80] -]]]; - -GVAR(HitScreamNamespace) setVariable ["Male06GRE", [[ - ["A3\sounds_f\characters\human-sfx\P15\Hit_Low_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P15\Hit_Low_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P15\Hit_Low_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P15\Hit_Low_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P15\Hit_Low_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P15\Hit_Mid_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P15\Hit_Mid_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P15\Hit_Mid_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P15\Hit_Mid_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P15\Hit_Mid_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P15\Hit_Max_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P15\Hit_Max_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P15\Hit_Max_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P15\Hit_Max_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P15\Hit_Max_5",3.1622777,1,80] -]]]; - -GVAR(HitScreamNamespace) setVariable ["Male04GRE", [[ - ["A3\sounds_f\characters\human-sfx\P16\Hit_Low_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P16\Hit_Low_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P16\Hit_Low_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P16\Hit_Low_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P16\Hit_Low_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P16\Hit_Mid_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P16\Hit_Mid_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P16\Hit_Mid_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P16\Hit_Mid_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P16\Hit_Mid_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P16\Hit_Max_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P16\Hit_Max_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P16\Hit_Max_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P16\Hit_Max_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P16\Hit_Max_5",3.1622777,1,80] -]]]; - -GVAR(HitScreamNamespace) setVariable ["Male05ENGB", [[ - ["A3\sounds_f\characters\human-sfx\P17\Hit_Low_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P17\Hit_Low_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P17\Hit_Low_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P17\Hit_Low_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P17\Hit_Low_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P17\Hit_Mid_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P17\Hit_Mid_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P17\Hit_Mid_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P17\Hit_Mid_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P17\Hit_Mid_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P17\Hit_Max_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P17\Hit_Max_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P17\Hit_Max_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P17\Hit_Max_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P17\Hit_Max_5",3.1622777,1,80] -]]]; - -GVAR(HitScreamNamespace) setVariable ["Male05ENG", [[ - ["A3\sounds_f\characters\human-sfx\P18\Hit_Low_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P18\Hit_Low_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P18\Hit_Low_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P18\Hit_Low_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P18\Hit_Low_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P18\Hit_Mid_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P18\Hit_Mid_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P18\Hit_Mid_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P18\Hit_Mid_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P18\Hit_Mid_5",3.1622777,1,80] -], [ - ["A3\sounds_f\characters\human-sfx\P18\Hit_Max_1",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P18\Hit_Max_2",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P18\Hit_Max_3",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P18\Hit_Max_4",3.1622777,1,80], - ["A3\sounds_f\characters\human-sfx\P18\Hit_Max_5",3.1622777,1,80] -]]]; - -// InjuredMoan -GVAR(InjuredMoanNamespace) = [] call CBA_fnc_createNamespace; -GVAR(InjuredMoanNamespace) setVariable ["#default", "Male08ENG"]; - -GVAR(InjuredMoanNamespace) setVariable ["Male08ENG", [[ - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Low_1",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Low_2",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Low_3",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Low_4",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Low_5",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Low_6",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Low_7",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Low_8",1.4125376,1,10] -], [ - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Mid_1",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Mid_2",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Mid_3",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Mid_4",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Mid_5",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Mid_6",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Mid_7",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Mid_8",1.5848932,1,15] -], [ - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Max_1",0.15848932,1,20], - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Max_2",0.15848932,1,20], - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Max_3",0.15848932,1,20], - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Max_4",0.15848932,1,20], - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Max_5",0.15848932,1,20], - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Max_6",0.15848932,1,20], - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Max_7",0.15848932,1,20], - ["A3\Sounds_F\characters\human-sfx\P01\Soundinjured_Max_8",0.15848932,1,20] -]]]; - -GVAR(InjuredMoanNamespace) setVariable ["Male06ENG", [[ - ["A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Low_1",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Low_2",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Low_3",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Low_4",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Low_5",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Low_6",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Low_7",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Low_8",1.4125376,1,10] -], [ - ["A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Mid_1",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Mid_2",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Mid_3",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Mid_4",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Mid_5",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Mid_6",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Mid_7",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Mid_8",1.5848932,1,15] -], [ - ["A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Max_1",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Max_2",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Max_3",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Max_4",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Max_5",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Max_6",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Max_7",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P02\Soundinjured_Max_8",1.7782794,1,20] -]]]; - -GVAR(InjuredMoanNamespace) setVariable ["Male09ENG", [[ - ["A3\Sounds_F\characters\human-sfx\P03\Soundinjured_Low_1",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P03\Soundinjured_Low_2",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P03\Soundinjured_Low_3",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P03\Soundinjured_Low_4",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P03\Soundinjured_Low_5",1.4125376,1,10] -], [ - ["A3\Sounds_F\characters\human-sfx\P03\Soundinjured_Mid_1",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P03\Soundinjured_Mid_2",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P03\Soundinjured_Mid_3",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P03\Soundinjured_Mid_4",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P03\Soundinjured_Mid_5",1.5848932,1,15] -], [ - ["A3\Sounds_F\characters\human-sfx\P03\Soundinjured_Max_1",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P03\Soundinjured_Max_2",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P03\Soundinjured_Max_3",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P03\Soundinjured_Max_4",1.7782794,1,20] -]]]; - -GVAR(InjuredMoanNamespace) setVariable ["Male07ENG", [[ - ["A3\Sounds_F\characters\human-sfx\P04\Soundinjured_Low_1",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P04\Soundinjured_Low_2",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P04\Soundinjured_Low_3",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P04\Soundinjured_Low_4",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P04\Soundinjured_Low_5",1.4125376,1,10] -], [ - ["A3\Sounds_F\characters\human-sfx\P04\Soundinjured_Mid_1",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P04\Soundinjured_Mid_2",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P04\Soundinjured_Mid_3",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P04\Soundinjured_Mid_4",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P04\Soundinjured_Mid_5",1.5848932,1,15] -], [ - ["A3\Sounds_F\characters\human-sfx\P04\Soundinjured_Max_1",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P04\Soundinjured_Max_2",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P04\Soundinjured_Max_3",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P04\Soundinjured_Max_4",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P04\Soundinjured_Max_5",1.7782794,1,20] -]]]; - -GVAR(InjuredMoanNamespace) setVariable ["Male03GRE", [[ - ["A3\Sounds_F\characters\human-sfx\P05\Soundinjured_Low_1",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P05\Soundinjured_Low_2",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P05\Soundinjured_Low_3",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P05\Soundinjured_Low_4",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P05\Soundinjured_Low_5",1.4125376,1,10] -], [ - ["A3\Sounds_F\characters\human-sfx\P05\Soundinjured_Mid_1",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P05\Soundinjured_Mid_2",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P05\Soundinjured_Mid_3",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P05\Soundinjured_Mid_4",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P05\Soundinjured_Mid_5",1.5848932,1,15] -], [ - ["A3\Sounds_F\characters\human-sfx\P05\Soundinjured_Max_1",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P05\Soundinjured_Max_2",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P05\Soundinjured_Max_3",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P05\Soundinjured_Max_4",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P05\Soundinjured_Max_5",1.7782794,1,20] -]]]; - -GVAR(InjuredMoanNamespace) setVariable ["Male02ENGB", [[ - ["A3\Sounds_F\characters\human-sfx\P06\Soundinjured_Low_1",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P06\Soundinjured_Low_2",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P06\Soundinjured_Low_3",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P06\Soundinjured_Low_4",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P06\Soundinjured_Low_5",1.4125376,1,10] -], [ - ["A3\Sounds_F\characters\human-sfx\P06\Soundinjured_Mid_1",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P06\Soundinjured_Mid_2",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P06\Soundinjured_Mid_3",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P06\Soundinjured_Mid_4",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P06\Soundinjured_Mid_5",1.5848932,1,15] -], [ - ["A3\Sounds_F\characters\human-sfx\P06\Soundinjured_Max_1",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P06\Soundinjured_Max_2",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P06\Soundinjured_Max_3",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P06\Soundinjured_Max_4",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P06\Soundinjured_Max_5",1.7782794,1,20] -]]]; - -GVAR(InjuredMoanNamespace) setVariable ["Male01ENGB", [[ - ["A3\Sounds_F\characters\human-sfx\P07\Soundinjured_Low_1",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P07\Soundinjured_Low_2",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P07\Soundinjured_Low_3",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P07\Soundinjured_Low_4",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P07\Soundinjured_Low_5",1.4125376,1,10] -], [ - ["A3\Sounds_F\characters\human-sfx\P07\Soundinjured_Mid_1",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P07\Soundinjured_Mid_2",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P07\Soundinjured_Mid_3",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P07\Soundinjured_Mid_4",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P07\Soundinjured_Mid_5",1.5848932,1,15] -], [ - ["A3\Sounds_F\characters\human-sfx\P07\Soundinjured_Max_1",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P07\Soundinjured_Max_2",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P07\Soundinjured_Max_3",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P07\Soundinjured_Max_4",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P07\Soundinjured_Max_5",1.7782794,1,20] -]]]; - -GVAR(InjuredMoanNamespace) setVariable ["Male01GRE", [[ - ["A3\Sounds_F\characters\human-sfx\P08\Soundinjured_Low_1",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P08\Soundinjured_Low_2",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P08\Soundinjured_Low_3",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P08\Soundinjured_Low_4",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P08\Soundinjured_Low_5",1.4125376,1,10] -], [ - ["A3\Sounds_F\characters\human-sfx\P08\Soundinjured_Mid_1",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P08\Soundinjured_Mid_2",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P08\Soundinjured_Mid_3",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P08\Soundinjured_Mid_4",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P08\Soundinjured_Mid_5",1.5848932,1,15] -], [ - ["A3\Sounds_F\characters\human-sfx\P08\Soundinjured_Max_1",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P08\Soundinjured_Max_2",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P08\Soundinjured_Max_3",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P08\Soundinjured_Max_4",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P08\Soundinjured_Max_5",1.7782794,1,20] -]]]; - -GVAR(InjuredMoanNamespace) setVariable ["Male02ENG", [[ - ["A3\Sounds_F\characters\human-sfx\P09\Soundinjured_Low_1",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P09\Soundinjured_Low_2",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P09\Soundinjured_Low_3",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P09\Soundinjured_Low_4",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P09\Soundinjured_Low_5",1.4125376,1,10] -], [ - ["A3\Sounds_F\characters\human-sfx\P09\Soundinjured_Mid_1",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P09\Soundinjured_Mid_2",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P09\Soundinjured_Mid_3",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P09\Soundinjured_Mid_4",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P09\Soundinjured_Mid_5",1.5848932,1,15] -], [ - ["A3\Sounds_F\characters\human-sfx\P09\Soundinjured_Max_1",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P09\Soundinjured_Max_2",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P09\Soundinjured_Max_3",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P09\Soundinjured_Max_4",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P09\Soundinjured_Max_5",1.7782794,1,20] -]]]; - -GVAR(InjuredMoanNamespace) setVariable ["Male02GRE", [[ - ["A3\Sounds_F\characters\human-sfx\P10\Soundinjured_Low_1",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P10\Soundinjured_Low_2",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P10\Soundinjured_Low_3",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P10\Soundinjured_Low_4",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P10\Soundinjured_Low_5",1.4125376,1,10] -], [ - ["A3\Sounds_F\characters\human-sfx\P10\Soundinjured_Mid_1",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P10\Soundinjured_Mid_2",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P10\Soundinjured_Mid_3",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P10\Soundinjured_Mid_4",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P10\Soundinjured_Mid_5",1.5848932,1,15] -], [ - ["A3\Sounds_F\characters\human-sfx\P10\Soundinjured_Max_1",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P10\Soundinjured_Max_2",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P10\Soundinjured_Max_3",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P10\Soundinjured_Max_4",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P10\Soundinjured_Max_5",1.7782794,1,20] -]]]; - -GVAR(InjuredMoanNamespace) setVariable ["Male03ENG", [[ - ["A3\Sounds_F\characters\human-sfx\P11\Soundinjured_Low_1",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P11\Soundinjured_Low_2",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P11\Soundinjured_Low_3",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P11\Soundinjured_Low_4",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P11\Soundinjured_Low_5",1.4125376,1,10] -], [ - ["A3\Sounds_F\characters\human-sfx\P11\Soundinjured_Mid_1",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P11\Soundinjured_Mid_2",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P11\Soundinjured_Mid_3",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P11\Soundinjured_Mid_4",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P11\Soundinjured_Mid_5",1.5848932,1,15] -], [ - ["A3\Sounds_F\characters\human-sfx\P11\Soundinjured_Max_1",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P11\Soundinjured_Max_2",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P11\Soundinjured_Max_3",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P11\Soundinjured_Max_4",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P11\Soundinjured_Max_5",1.7782794,1,20] -]]]; - -GVAR(InjuredMoanNamespace) setVariable ["Male03ENGB", [[ - ["A3\Sounds_F\characters\human-sfx\P12\Soundinjured_Low_1",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P12\Soundinjured_Low_2",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P12\Soundinjured_Low_3",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P12\Soundinjured_Low_4",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P12\Soundinjured_Low_5",1.4125376,1,10] -], [ - ["A3\Sounds_F\characters\human-sfx\P12\Soundinjured_Mid_1",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P12\Soundinjured_Mid_2",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P12\Soundinjured_Mid_3",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P12\Soundinjured_Mid_4",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P12\Soundinjured_Mid_5",1.5848932,1,15] -], [ - ["A3\Sounds_F\characters\human-sfx\P12\Soundinjured_Max_1",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P12\Soundinjured_Max_2",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P12\Soundinjured_Max_3",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P12\Soundinjured_Max_4",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P12\Soundinjured_Max_5",1.7782794,1,20] -]]]; - -GVAR(InjuredMoanNamespace) setVariable ["Male04ENG", [[ - ["A3\Sounds_F\characters\human-sfx\P13\Soundinjured_Low_1",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P13\Soundinjured_Low_2",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P13\Soundinjured_Low_3",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P13\Soundinjured_Low_4",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P13\Soundinjured_Low_5",1.4125376,1,10] -], [ - ["A3\Sounds_F\characters\human-sfx\P13\Soundinjured_Mid_1",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P13\Soundinjured_Mid_2",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P13\Soundinjured_Mid_3",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P13\Soundinjured_Mid_4",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P13\Soundinjured_Mid_5",1.5848932,1,15] -], [ - ["A3\Sounds_F\characters\human-sfx\P13\Soundinjured_Max_1",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P13\Soundinjured_Max_2",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P13\Soundinjured_Max_3",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P13\Soundinjured_Max_4",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P13\Soundinjured_Max_5",1.7782794,1,20] -]]]; - -GVAR(InjuredMoanNamespace) setVariable ["Male05GRE", [[ - ["A3\Sounds_F\characters\human-sfx\P14\Soundinjured_Low_1",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P14\Soundinjured_Low_2",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P14\Soundinjured_Low_3",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P14\Soundinjured_Low_4",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P14\Soundinjured_Low_5",1.4125376,1,10] -], [ - ["A3\Sounds_F\characters\human-sfx\P14\Soundinjured_Mid_1",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P14\Soundinjured_Mid_2",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P14\Soundinjured_Mid_3",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P14\Soundinjured_Mid_4",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P14\Soundinjured_Mid_5",1.5848932,1,15] -], [ - ["A3\Sounds_F\characters\human-sfx\P14\Soundinjured_Max_1",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P14\Soundinjured_Max_2",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P14\Soundinjured_Max_3",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P14\Soundinjured_Max_4",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P14\Soundinjured_Max_5",1.7782794,1,20] -]]]; - -GVAR(InjuredMoanNamespace) setVariable ["Male06GRE", [[ - ["A3\Sounds_F\characters\human-sfx\P15\Soundinjured_Low_1",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P15\Soundinjured_Low_2",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P15\Soundinjured_Low_3",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P15\Soundinjured_Low_4",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P15\Soundinjured_Low_5",1.4125376,1,10] -], [ - ["A3\Sounds_F\characters\human-sfx\P15\Soundinjured_Mid_1",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P15\Soundinjured_Mid_2",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P15\Soundinjured_Mid_3",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P15\Soundinjured_Mid_4",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P15\Soundinjured_Mid_5",1.5848932,1,15] -], [ - ["A3\Sounds_F\characters\human-sfx\P15\Soundinjured_Max_1",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P15\Soundinjured_Max_2",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P15\Soundinjured_Max_3",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P15\Soundinjured_Max_4",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P15\Soundinjured_Max_5",1.7782794,1,20] -]]]; - -GVAR(InjuredMoanNamespace) setVariable ["Male04GRE", [[ - ["A3\Sounds_F\characters\human-sfx\P16\Soundinjured_Low_1",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P16\Soundinjured_Low_2",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P16\Soundinjured_Low_3",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P16\Soundinjured_Low_4",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P16\Soundinjured_Low_5",1.4125376,1,10] -], [ - ["A3\Sounds_F\characters\human-sfx\P16\Soundinjured_Mid_1",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P16\Soundinjured_Mid_2",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P16\Soundinjured_Mid_3",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P16\Soundinjured_Mid_4",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P16\Soundinjured_Mid_5",1.5848932,1,15] -], [ - ["A3\Sounds_F\characters\human-sfx\P16\Soundinjured_Max_1",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P16\Soundinjured_Max_2",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P16\Soundinjured_Max_3",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P16\Soundinjured_Max_4",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P16\Soundinjured_Max_5",1.7782794,1,20] -]]]; - -GVAR(InjuredMoanNamespace) setVariable ["Male05ENGB", [[ - ["A3\Sounds_F\characters\human-sfx\P17\Soundinjured_Low_1",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P17\Soundinjured_Low_2",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P17\Soundinjured_Low_3",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P17\Soundinjured_Low_4",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P17\Soundinjured_Low_5",1.4125376,1,10] -], [ - ["A3\Sounds_F\characters\human-sfx\P17\Soundinjured_Mid_1",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P17\Soundinjured_Mid_2",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P17\Soundinjured_Mid_3",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P17\Soundinjured_Mid_4",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P17\Soundinjured_Mid_5",1.5848932,1,15] -], [ - ["A3\Sounds_F\characters\human-sfx\P17\Soundinjured_Max_1",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P17\Soundinjured_Max_2",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P17\Soundinjured_Max_3",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P17\Soundinjured_Max_4",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P17\Soundinjured_Max_5",1.7782794,1,20] -]]]; - -GVAR(InjuredMoanNamespace) setVariable ["Male05ENG", [[ - ["A3\Sounds_F\characters\human-sfx\P18\Soundinjured_Low_1",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P18\Soundinjured_Low_2",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P18\Soundinjured_Low_3",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P18\Soundinjured_Low_4",1.4125376,1,10], - ["A3\Sounds_F\characters\human-sfx\P18\Soundinjured_Low_5",1.4125376,1,10] -], [ - ["A3\Sounds_F\characters\human-sfx\P18\Soundinjured_Mid_1",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P18\Soundinjured_Mid_2",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P18\Soundinjured_Mid_3",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P18\Soundinjured_Mid_4",1.5848932,1,15], - ["A3\Sounds_F\characters\human-sfx\P18\Soundinjured_Mid_5",1.5848932,1,15] -], [ - ["A3\Sounds_F\characters\human-sfx\P18\Soundinjured_Max_1",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P18\Soundinjured_Max_2",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P18\Soundinjured_Max_3",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P18\Soundinjured_Max_4",1.7782794,1,20], - ["A3\Sounds_F\characters\human-sfx\P18\Soundinjured_Max_5",1.7782794,1,20] -]]]; - ADDON = true; diff --git a/addons/medical_feedback/functions/fnc_effectBleeding.sqf b/addons/medical_feedback/functions/fnc_effectBleeding.sqf index cf87d2eb35..0f04ffd333 100644 --- a/addons/medical_feedback/functions/fnc_effectBleeding.sqf +++ b/addons/medical_feedback/functions/fnc_effectBleeding.sqf @@ -6,6 +6,7 @@ * Arguments: * 0: Enable effect * 1: Current bloodloss (in l/s) + * 2: Instant change (optional, default false) * * Return Value: * None @@ -16,7 +17,7 @@ * Public: No */ -params ["_enable", "_bloodloss"]; +params ["_enable", "_bloodloss", ["_instant", false]]; if (isNull findDisplay 46) exitWith {}; private _controls = uiNamespace getVariable [QGVAR(bloodControls), [controlNull, controlNull]]; @@ -54,10 +55,7 @@ if (isNull _blood1) then { private _fade = linearConversion [0, 0.002, _bloodloss, 1, 0, true]; -private _switchBloodFadeInfo = missionNamespace getVariable [QGVAR(switchBloodFadeInfo), [0, 0]]; -_switchBloodFadeInfo params ["_tickCounter", "_lastBloodloss"]; - -if (_tickCounter == 2) then { +if (GVAR(bloodTickCounter) == 2 || _instant) then { if (ctrlFade _blood1 > ctrlFade _blood2) then { _blood1 ctrlSetFade _fade; _blood2 ctrlSetFade 1; @@ -66,16 +64,15 @@ if (_tickCounter == 2) then { _blood2 ctrlSetFade _fade; }; - _blood1 ctrlCommit 3; - _blood2 ctrlCommit 3; + if (_instant) then { + _blood1 ctrlCommit 0.3; + _blood2 ctrlCommit 0.3; + } else { + _blood1 ctrlCommit 3; + _blood2 ctrlCommit 3; + }; - GVAR(switchBloodFadeInfo) = [0, _bloodloss]; + GVAR(bloodTickCounter) = 0; } else { - GVAR(switchBloodFadeInfo) = [_tickCounter + 1, _bloodloss]; -}; - -// Speed up fade on sudden changes -if (abs (_lastBloodloss - _bloodloss) > 0.001) then { - _blood1 ctrlCommit 1; - _blood2 ctrlCommit 1; + GVAR(bloodTickCounter) = GVAR(bloodTickCounter) + 1; }; diff --git a/addons/medical_feedback/functions/fnc_effectHeartBeat.sqf b/addons/medical_feedback/functions/fnc_effectHeartBeat.sqf index 1c5c9ef968..283d3edcb6 100644 --- a/addons/medical_feedback/functions/fnc_effectHeartBeat.sqf +++ b/addons/medical_feedback/functions/fnc_effectHeartBeat.sqf @@ -34,7 +34,6 @@ switch (true) do { case (_heartRate < 60): { playSound SND_HEARBEAT_SLOW; [FUNC(effectHeartBeat), [], _waitTime] call CBA_fnc_waitAndExecute; - }; default { TRACE_1("Ending heart beat effect - normal",_heartRate); diff --git a/addons/medical_feedback/functions/fnc_effectPain.sqf b/addons/medical_feedback/functions/fnc_effectPain.sqf index 1cfa68ff1c..96f233a4b9 100644 --- a/addons/medical_feedback/functions/fnc_effectPain.sqf +++ b/addons/medical_feedback/functions/fnc_effectPain.sqf @@ -20,25 +20,41 @@ params ["_enable", "_intensity"]; if (!_enable || {_intensity == 0}) exitWith { GVAR(ppPain) ppEffectEnable false; + GVAR(ppPainBlur) ppEffectEnable false; }; GVAR(ppPain) ppEffectEnable true; +GVAR(ppPainBlur) ppEffectEnable true; // Trigger effect every 2s private _showNextTick = missionNamespace getVariable [QGVAR(showPainNextTick), true]; GVAR(showPainNextTick) = !_showNextTick; if (_showNextTick) exitWith {}; +private _blurIntensity = linearConversion [0.8, 1, _intensity, 0, 1, true]; +GVAR(ppPainBlur) ppEffectAdjust [_blurIntensity]; +GVAR(ppPainBlur) ppEffectCommit 0.1; + +if (GVAR(painEffectType) == FX_PAIN_ONLY_BASE) exitWith {}; + private _initialAdjust = []; private _delayedAdjust = []; -if (GVAR(painEffectType) == 0) then { - _intensity = linearConversion [0, 1, _intensity, 0, 0.6, true]; - _initialAdjust = [1, 1, 0, [1, 1, 1, _intensity], [1, 1, 1, 1], [0.33, 0.33, 0.33, 0], [0.59, 0.64, 0, 0, 0, 0, 4]]; - _delayedAdjust = [1, 1, 0, [1, 1, 1, 0], [1, 1, 1, 1], [0.33, 0.33, 0.33, 0], [0.59, 0.64, 0, 0, 0, 0, 4]]; -} else { - _intensity = linearConversion [0, 1, _intensity, 0, 0.008, true]; - _initialAdjust = [_intensity, _intensity, 0.3, 0.39]; - _delayedAdjust = [ 0, 0, 0.3, 0.39]; +switch (GVAR(painEffectType)) do { + case FX_PAIN_WHITE_FLASH: { + _intensity = linearConversion [0, 1, _intensity, 0, 0.6, true]; + _initialAdjust = [1, 1, 0, [1, 1, 1, _intensity ], [1, 1, 1, 1], [0.33, 0.33, 0.33, 0], [0.55, 0.5, 0, 0, 0, 0, 4]]; + _delayedAdjust = [1, 1, 0, [1, 1, 1, _intensity * 0.3], [1, 1, 1, 1], [0.33, 0.33, 0.33, 0], [0.55, 0.5, 0, 0, 0, 0, 4]]; + }; + case FX_PAIN_PULSATING_BLUR: { + _intensity = linearConversion [0, 1, _intensity, 0, 0.008, true]; + _initialAdjust = [_intensity , _intensity , 0.15, 0.15]; + _delayedAdjust = [_intensity * 0.2, _intensity * 0.2, 0.25, 0.25]; + }; + case FX_PAIN_CHROMATIC_ABERRATION: { + _intensity = linearConversion [0, 1, _intensity, 0, 0.06, true]; + _initialAdjust = [_intensity , _intensity , true]; + _delayedAdjust = [_intensity * 0.15, _intensity * 0.15, true]; + }; }; GVAR(ppPain) ppEffectAdjust _initialAdjust; diff --git a/addons/medical_feedback/functions/fnc_handleEffects.sqf b/addons/medical_feedback/functions/fnc_handleEffects.sqf index e4e536c4f4..b065d42646 100644 --- a/addons/medical_feedback/functions/fnc_handleEffects.sqf +++ b/addons/medical_feedback/functions/fnc_handleEffects.sqf @@ -5,7 +5,7 @@ * Note: Heart beat sounds run in a different PFH - see fnc_effectHeartBeat. * * Arguments: - * None + * 0: Manual, instant update (optional, default false) * * Return Value: * None @@ -15,6 +15,7 @@ * * Public: No */ +params [["_manualUpdate", false]]; if (EGVAR(common,OldIsCamera) || {!alive ACE_player}) exitWith { [false, 0] call FUNC(effectUnconscious); @@ -44,10 +45,7 @@ if ((!GVAR(heartBeatEffectRunning)) && {_heartRate != 0} && {(_heartRate > 160) true, linearConversion [BLOOD_VOLUME_CLASS_2_HEMORRHAGE, BLOOD_VOLUME_CLASS_4_HEMORRHAGE, _bloodVolume, 0, 1, true] ] call FUNC(effectBloodVolume); -if (!_unconscious) then { - [true, _pain] call FUNC(effectPain); -}; - -[true, _bleedingStrength] call FUNC(effectBleeding); +[!_unconscious, _pain] call FUNC(effectPain); +[!_unconscious, _bleedingStrength, _manualUpdate] call FUNC(effectBleeding); END_COUNTER(handleEffects); diff --git a/addons/medical_feedback/functions/fnc_initEffects.sqf b/addons/medical_feedback/functions/fnc_initEffects.sqf index 66099d5806..11bee29651 100644 --- a/addons/medical_feedback/functions/fnc_initEffects.sqf +++ b/addons/medical_feedback/functions/fnc_initEffects.sqf @@ -35,27 +35,45 @@ if (!isNil QGVAR(ppPain)) then { TRACE_1("delete pain",GVAR(ppPain)); ppEffectDestroy GVAR(ppPain) }; -if (GVAR(painEffectType) == 0) then { - GVAR(ppPain) = [ - "ColorCorrections", - 13502, - [1, 1, 0, [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] - ] call _fnc_createEffect; -} else { - GVAR(ppPain) = [ - "RadialBlur", // "Will not do anything if RADIAL BLUR is disabled in Video Options." - 13502, - [0, 0, 0.3, 0.39] +switch (GVAR(painEffectType)) do { + case FX_PAIN_WHITE_FLASH: { + GVAR(ppPain) = [ + "ColorCorrections", + 13502, + [1, 1, 0, [1, 1, 1, 0], [1, 1, 1, 1], [0.33, 0.33, 0.33, 0], [0.55, 0.5, 0, 0, 0, 0, 4]] + ] call _fnc_createEffect; + }; + case FX_PAIN_PULSATING_BLUR: { + GVAR(ppPain) = [ + "RadialBlur", // "Will not do anything if RADIAL BLUR is disabled in Video Options." + 13502, + [0, 0, 0.25, 0.25] + ] call _fnc_createEffect; + }; + case FX_PAIN_CHROMATIC_ABERRATION: { + GVAR(ppPain) = [ + "ChromAberration", + 13502, + [0, 0, false] + ] call _fnc_createEffect; + }; +}; +// Base blur on high pain +if (isNil QGVAR(ppPainBlur)) then { + GVAR(ppPainBlur) = [ + "DynamicBlur", + 813, // 135xx does not work + [0] ] call _fnc_createEffect; }; -TRACE_1("created pain",GVAR(ppPain)); +TRACE_1("created pain",GVAR(ppPain)); if (_justPain) exitWith {}; // - Unconscious -------------------------------------------------------------- GVAR(ppUnconsciousBlur) = [ "DynamicBlur", - 813, // 135xx does not work + 814, // 135xx does not work [0] ] call _fnc_createEffect; @@ -82,6 +100,6 @@ GVAR(ppIncapacitationGlare) = [ GVAR(ppIncapacitationBlur) = [ "DynamicBlur", - 814, // 135xx does not work + 815, // 135xx does not work [0] ] call _fnc_createEffect; diff --git a/addons/medical_feedback/functions/fnc_playInjuredSound.sqf b/addons/medical_feedback/functions/fnc_playInjuredSound.sqf index 98739d5b30..09c267400c 100644 --- a/addons/medical_feedback/functions/fnc_playInjuredSound.sqf +++ b/addons/medical_feedback/functions/fnc_playInjuredSound.sqf @@ -26,60 +26,43 @@ params [["_unit", objNull, [objNull]], ["_type", "hit", [""]], ["_severity", 0, if (!local _unit) exitWith { ERROR("Unit not local or null"); }; - if !(_unit call EFUNC(common,isAwake)) exitWith {}; -private _timeOut = [TIME_OUT_HIT, TIME_OUT_MOAN] select (_type == "moan"); - // Handle timeout +private _timeOut = [TIME_OUT_HIT, TIME_OUT_MOAN] select (_type == "moan"); if (_unit getVariable [QGVAR(soundTimeout) + _type, -1] > CBA_missionTime) exitWith {}; _unit setVariable [QGVAR(soundTimeout) + _type, CBA_missionTime + _timeOut]; -// Get sounds -private _soundsNamespace = NAMESPACE_NULL; - -switch (toLower _type) do { - case ("hit"): { - _soundsNamespace = GVAR(HitScreamNamespace); - }; - case ("moan"): { - _soundsNamespace = GVAR(InjuredMoanNamespace); - }; -}; - // Get units speaker private _speaker = speaker _unit; - if (_speaker == "ACE_NoVoice") then { _speaker = _unit getVariable "ace_originalSpeaker"; }; -private _sounds = _soundsNamespace getVariable _speaker; - -if (isNil "_sounds") then { - _sounds = _soundsNamespace getVariable (_soundsNamespace getVariable "#default"); +// Fallback if speaker has no associated scream/moan sound +if (isNull (configFile >> "CfgSounds" >> format ["ACE_moan_%1_low_1", _speaker])) then { + _speaker = "Male08ENG"; }; -if (isNil "_sounds") exitWith { - ERROR("No sounds for speaker and no default found"); +// Select actual sound +private _variation = ["low", "mid", "high"] select _severity; +private _distance = if (_type == "hit") then { + [50, 60, 70] select _severity; +} else { + [10, 15, 20] select _severity; }; -// Get correct sound of the speaker -_sounds = _sounds param [_severity, []]; -(selectRandom _sounds) params ["_sound", ["_volume", 1], ["_frequency", 1], ["_distance", 80]]; - -if (isNil "_sound") exitWith { - ERROR("No sound for this speaker"); +private _cfgSounds = configFile >> "CfgSounds"; +private _targetClass = format ["ACE_%1_%2_%3_", _type, _speaker, _variation]; +private _index = 1; +private _sounds = []; +while {isClass (_cfgSounds >> (_targetClass + str _index))} do { + _sounds pushBack (_cfgSounds >> (_targetClass + str _index)); + _index = _index + 1; }; +private _sound = configName selectRandom _sounds; +if (isNil "_sound") exitWith { WARNING_1("no sounds for target [%1]",_targetClass); }; -// Delete leading slash. -if (_sound select [0, 1] == "\") then { - _sound = _sound select [1]; -}; - -// Default file extension. -if (_sound find "." == -1) then { - _sound = _sound + ".wss"; -}; - -playSound3D [_sound, objNull, false, position _unit, _volume, _frequency, _distance]; +// Limit network traffic by only sending the event to players who can potentially hear it +private _targets = _unit nearEntities ["CAManBase", _distance]; +[QGVAR(forceSay3D), [_unit, _sound, _distance], _targets] call CBA_fnc_targetEvent; diff --git a/addons/medical_feedback/initSettings.sqf b/addons/medical_feedback/initSettings.sqf index 9dd0e957c4..6d0965fe9f 100644 --- a/addons/medical_feedback/initSettings.sqf +++ b/addons/medical_feedback/initSettings.sqf @@ -1,21 +1,20 @@ -// CBA Settings [ADDON: ace_medical_feedback]: - -private _categoryArray = [LELSTRING(medical,Category_DisplayName), LLSTRING(subCategory)]; - [ QGVAR(painEffectType), "LIST", - [localize LSTRING(painEffectType), "Selects the used pain effect type"], //@todo - _categoryArray, + [LSTRING(PainEffectType_DisplayName), LSTRING(PainEffectType_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], [ - [0, 1], - [LLSTRING(painEffectType_whiteFlashing), LLSTRING(painEffectType_pulsingBlur)], + [FX_PAIN_WHITE_FLASH, FX_PAIN_PULSATING_BLUR, FX_PAIN_CHROMATIC_ABERRATION, FX_PAIN_ONLY_BASE], + [LSTRING(painEffectType_whiteFlashing), LSTRING(painEffectType_pulsingBlur), LSTRING(painEffectType_chromAberration), LSTRING(painEffectType_onlyBase)], 0 ], false, { - if (isNil QGVAR(ppPain)) exitWith {TRACE_1("Before Post-Init",_this)}; - TRACE_1("reseting ppEffect type",_this); + if (isNil QGVAR(ppPain)) exitWith { + TRACE_1("painEffectType setting - before postInit",_this); + }; + + TRACE_1("painEffectType setting - resetting effect",_this); [true] call FUNC(initEffects); } ] call CBA_Settings_fnc_init; diff --git a/addons/medical_feedback/script_component.hpp b/addons/medical_feedback/script_component.hpp index e39fa42c8b..78d72ed3da 100644 --- a/addons/medical_feedback/script_component.hpp +++ b/addons/medical_feedback/script_component.hpp @@ -34,5 +34,11 @@ #define SND_HEARBEAT_FAST (selectRandom ["ACE_heartbeat_fast_1", "ACE_heartbeat_fast_2", "ACE_heartbeat_fast_3"]) #define SND_HEARBEAT_NORMAL (selectRandom ["ACE_heartbeat_norm_1", "ACE_heartbeat_norm_2"]) #define SND_HEARBEAT_SLOW (selectRandom ["ACE_heartbeat_slow_1", "ACE_heartbeat_slow_2"]) +#define SND_FRACTURE (selectRandom ["ACE_fracture_1", "ACE_fracture_2", "ACE_fracture_3", "ACE_fracture_4"]) #define VOL_UNCONSCIOUS 0.25 + +#define FX_PAIN_WHITE_FLASH 0 +#define FX_PAIN_PULSATING_BLUR 1 +#define FX_PAIN_CHROMATIC_ABERRATION 2 +#define FX_PAIN_ONLY_BASE 3 diff --git a/addons/medical_feedback/sounds/fracture_1.wav b/addons/medical_feedback/sounds/fracture_1.wav new file mode 100644 index 0000000000..b68a71da55 Binary files /dev/null and b/addons/medical_feedback/sounds/fracture_1.wav differ diff --git a/addons/medical_feedback/sounds/fracture_2.wav b/addons/medical_feedback/sounds/fracture_2.wav new file mode 100644 index 0000000000..2725a8769e Binary files /dev/null and b/addons/medical_feedback/sounds/fracture_2.wav differ diff --git a/addons/medical_feedback/sounds/fracture_3.wav b/addons/medical_feedback/sounds/fracture_3.wav new file mode 100644 index 0000000000..c96126b15c Binary files /dev/null and b/addons/medical_feedback/sounds/fracture_3.wav differ diff --git a/addons/medical_feedback/sounds/fracture_4.wav b/addons/medical_feedback/sounds/fracture_4.wav new file mode 100644 index 0000000000..0ff6a9e008 Binary files /dev/null and b/addons/medical_feedback/sounds/fracture_4.wav differ diff --git a/addons/medical_feedback/stringtable.xml b/addons/medical_feedback/stringtable.xml index 9e2e45efaa..d8d6a3420b 100644 --- a/addons/medical_feedback/stringtable.xml +++ b/addons/medical_feedback/stringtable.xml @@ -1,10 +1,71 @@ + + Feedback + Feedback + フィードバック + Реакция на ранения + Réaction aux blessures + Reação a Lesões + + + Pain Effect Type + Schmerzeffekt-Typ + Rodzaj efektu bólu + Визуальный эффект боли + Pain Effect Type + Tipo de efecto de dolor + Effet de douleur + Fájdalom-effekt típusa + Tipo do efeito de dor + Typ bolesti - efekt + 痛み効果の種類 + 고통 효과 종류 + + + Selects the used pain effect type. + 痛みの効果の種類を選択できます。 + Permet de choisir quel effet provoque la douleur. + Выбирает тип визуализации болевого эффекта. + Selecione o tipo de efeito de dor. + + + White Flashing + Weißes blinken + 白く点滅 + Белые вспышки + Flash blancs + Flashes Brancos + + + Pulsing Blur + Wiederkehrende Unschärfe + ボケの強弱 + Пульсирующее размытие + Pulsations floues + Borrão Pulsante + + + Chromatic Aberration + Chromatische Aberration + Aberracja chromatyczna + Хроматическая аберрация + Aberrazione cromatica + Aberración cromática + Aberration chromatique + Kromatikus aberráció + Chromatická aberace + Aberração cromática + 色の収差 + 색수차 + 色差 + 色差 + + + Only high pain effect + - - Feedback - Enable Screams Включить крики @@ -13,7 +74,7 @@ Schreie aktivieren Povolit křik Ativar gritos - Activer les hurlements + Activer les cris Kiáltások engedélyezése Abilita Grida 叫びを有効化 @@ -29,34 +90,14 @@ Aktiviere Schreie bei verletzten Einheiten Povolit křičení zraněných jednotek Ativa gritos para unidades feridas - Active les hurlements d'unités blessées + 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 - 負傷したユニットが叫ぶように + 負傷したユニットを叫ぶようにします。 부상당한 인원이 소리지르는것을 활성화합니다 启用伤者的尖叫声 啟用傷者的尖叫聲 - - Pain Effect Type - Schmerzeffekt-Typ - Rodzaj efektu bólu - Визуальный эффект боли - Pain Effect Type - Tipo de efecto de dolor - Type d'effet de douleur - Fájdalom-effekt típusa - Tipo do efeito de dor - Typ bolesti - efekt - 痛みの種類 - 고통 효과 종류 - - - White flashing - - - Pulsing blur - diff --git a/addons/medical_gui/CfgVehicles.hpp b/addons/medical_gui/CfgVehicles.hpp index 3d11924bf3..eecae9a359 100644 --- a/addons/medical_gui/CfgVehicles.hpp +++ b/addons/medical_gui/CfgVehicles.hpp @@ -44,11 +44,11 @@ class CfgVehicles { #include "InteractionBodyParts.hpp" #undef ACTION_CONDITION }; - class ACE_LoadPatient { + class ACE_LoadPatient { displayName = CSTRING(LoadPatient); condition = QUOTE(_target getVariable [ARR_2('ACE_isUnconscious',false)] && {alive _target} && {vehicle _target == _target}); exceptions[] = {"isNotDragging", "isNotCarrying"}; - statement = QUOTE([ARR_2(_player, _target)] call EFUNC(medical_treatment,actionLoadUnit)); + statement = QUOTE([ARR_2(_player, _target)] call EFUNC(medical_treatment,loadUnit)); icon = QPATHTOF(ui\cross.paa); insertChildren = QUOTE(call DEFUNC(medical_treatment,addLoadPatientActions)); }; @@ -56,7 +56,7 @@ class CfgVehicles { displayName = CSTRING(UnloadPatient); condition = QUOTE(_target getVariable [ARR_2('ACE_isUnconscious',false)] && {vehicle _target != _target} && {vehicle _player == _player}); exceptions[] = {"isNotDragging", "isNotCarrying", "isNotInside"}; - statement = QUOTE([ARR_2(_player, _target)] call EFUNC(medical_treatment,actionUnloadUnit)); + statement = QUOTE([ARR_2(_player, _target)] call EFUNC(medical_treatment,unloadUnit)); icon = QPATHTOF(ui\cross.paa); }; }; diff --git a/addons/medical_gui/data/body_image/arm_left_b.paa b/addons/medical_gui/data/body_image/arm_left_b.paa new file mode 100644 index 0000000000..9d4cefd89b Binary files /dev/null and b/addons/medical_gui/data/body_image/arm_left_b.paa differ diff --git a/addons/medical_gui/data/body_image/arm_right_b.paa b/addons/medical_gui/data/body_image/arm_right_b.paa new file mode 100644 index 0000000000..c5ae90dcbf Binary files /dev/null and b/addons/medical_gui/data/body_image/arm_right_b.paa differ diff --git a/addons/medical_gui/data/body_image/leg_left_b.paa b/addons/medical_gui/data/body_image/leg_left_b.paa new file mode 100644 index 0000000000..f878074995 Binary files /dev/null and b/addons/medical_gui/data/body_image/leg_left_b.paa differ diff --git a/addons/medical_gui/data/body_image/leg_right_b.paa b/addons/medical_gui/data/body_image/leg_right_b.paa new file mode 100644 index 0000000000..3b0dc02605 Binary files /dev/null and b/addons/medical_gui/data/body_image/leg_right_b.paa differ diff --git a/addons/medical_gui/functions/fnc_displayPatientInformation.sqf b/addons/medical_gui/functions/fnc_displayPatientInformation.sqf index 25f87f93ce..ac76d34012 100644 --- a/addons/medical_gui/functions/fnc_displayPatientInformation.sqf +++ b/addons/medical_gui/functions/fnc_displayPatientInformation.sqf @@ -53,7 +53,7 @@ if (isNull _display) then { // Update activity log private _ctrlActivityLog = _display displayCtrl IDC_ACTIVITY; - private _activityLog = _target getVariable [QEGVAR(medical,logFile_activity_view), []]; + private _activityLog = _target getVariable [MED_LOG_VARNAME("activity"), []]; [_ctrlActivityLog, _activityLog] call FUNC(updateLogList); // Update triage status diff --git a/addons/medical_gui/functions/fnc_menuPFH.sqf b/addons/medical_gui/functions/fnc_menuPFH.sqf index 9d24ffd6d3..c2dc7a277f 100644 --- a/addons/medical_gui/functions/fnc_menuPFH.sqf +++ b/addons/medical_gui/functions/fnc_menuPFH.sqf @@ -19,7 +19,7 @@ if !([ACE_player, GVAR(target), ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith) && {[ACE_player, GVAR(target)] call FUNC(canOpenMenu)}) then { closeDialog 0; // Show hint if distance condition failed - if (ACE_player distance GVAR(target) > GVAR(maxDistance)) then { + if ((ACE_player distance GVAR(target) > GVAR(maxDistance)) && {vehicle ACE_player != vehicle GVAR(target)}) then { [[ELSTRING(medical,DistanceToFar), GVAR(target) call EFUNC(common,getName)], 2] call EFUNC(common,displayTextStructured); }; }; @@ -44,11 +44,11 @@ private _ctrlBodyImage = _display displayCtrl IDC_BODY_GROUP; // Update activity and quick view logs private _ctrlActivityLog = _display displayCtrl IDC_ACTIVITY; -private _activityLog = GVAR(target) getVariable [QEGVAR(medical,logFile_activity_view), []]; +private _activityLog = GVAR(target) getVariable [MED_LOG_VARNAME("activity"), []]; [_ctrlActivityLog, _activityLog] call FUNC(updateLogList); private _ctrlQuickView = _display displayCtrl IDC_QUICKVIEW; -private _quickView = GVAR(target) getVariable [QEGVAR(medical,logFile_quick_view), []]; +private _quickView = GVAR(target) getVariable [MED_LOG_VARNAME("quick_view"), []]; [_ctrlQuickView, _quickView] call FUNC(updateLogList); // Update triage status diff --git a/addons/medical_gui/functions/fnc_modifyAction.sqf b/addons/medical_gui/functions/fnc_modifyAction.sqf index d4754dab06..422c73a475 100644 --- a/addons/medical_gui/functions/fnc_modifyAction.sqf +++ b/addons/medical_gui/functions/fnc_modifyAction.sqf @@ -25,12 +25,12 @@ private _bloodLossOnBodyPart = 0; // Add all bleeding from wounds on selection { - _x params ["", "", "_bodyPartN", "_amountOf", "_bleeding"]; + _x params ["", "_bodyPartN", "_amountOf", "_bleeding"]; if (_bodyPartN == _partIndex) then { _bloodLossOnBodyPart = _bloodLossOnBodyPart + (_amountOf * _bleeding); }; -} forEach (_target getvariable [QEGVAR(medical,openWounds), []]); +} forEach GET_OPEN_WOUNDS(_target); private _frBL = 0 max (_bloodLossOnBodyPart / BLOOD_LOSS_RED_THRESHOLD) min 1; private _colorInt = ceil (_frBL * (BLOOD_LOSS_TOTAL_COLORS - 1)); // ceil because any bleeding more than zero shouldn't be white diff --git a/addons/medical_gui/functions/fnc_onMenuClose.sqf b/addons/medical_gui/functions/fnc_onMenuClose.sqf index bc65e975fd..a531eca4e8 100644 --- a/addons/medical_gui/functions/fnc_onMenuClose.sqf +++ b/addons/medical_gui/functions/fnc_onMenuClose.sqf @@ -18,5 +18,6 @@ if (EGVAR(interact_menu,menuBackground) == 1) then {[QGVAR(id), false] call EFUNC(common,blurScreen)}; if (EGVAR(interact_menu,menuBackground) == 2) then {(uiNamespace getVariable [QEGVAR(interact_menu,menuBackground), displayNull]) closeDisplay 0}; +GVAR(pendingReopen) = false; GVAR(menuPFH) call CBA_fnc_removePerFrameHandler; GVAR(menuPFH) = -1; diff --git a/addons/medical_gui/functions/fnc_onMenuOpen.sqf b/addons/medical_gui/functions/fnc_onMenuOpen.sqf index be4707918f..b6c326f590 100644 --- a/addons/medical_gui/functions/fnc_onMenuOpen.sqf +++ b/addons/medical_gui/functions/fnc_onMenuOpen.sqf @@ -42,3 +42,32 @@ if (GVAR(menuPFH) != -1) exitWith { }; GVAR(menuPFH) = [FUNC(menuPFH), 0, []] call CBA_fnc_addPerFrameHandler; + +// Hide categories if they don't have any actions (airway) +private _list = [ + [IDC_TRIAGE, true], + [IDC_EXAMINE, true], + [IDC_BANDAGE, "bandage"], + [IDC_MEDICATION, "medication"], + [IDC_AIRWAY, "airway"], + [IDC_ADVANCED, "advanced"], + [IDC_DRAG, "drag"], + [IDC_TOGGLE, true] +]; +private _countEnabled = { + _x params ["", "_category"]; + if (_category isEqualType "") then { _x set [1, (GVAR(actions) findIf {_category == _x select 1}) > -1]; }; + _x select 1 +} count _list; +private _offsetX = POS_X(1.5) + 0.5 * (POS_X(12) - POS_X(_countEnabled * 1.5)); +{ + _x params ["_idc", "_enabled"]; + private _ctrl = _display displayCtrl _idc; + if (_enabled) then { + _ctrl ctrlSetPositionX _offsetX; + _ctrl ctrlCommit 0; + _offsetX = _offsetX + POS_W(1.5); + } else { + _ctrl ctrlShow false; + }; +} forEach _list; diff --git a/addons/medical_gui/functions/fnc_updateBodyImage.sqf b/addons/medical_gui/functions/fnc_updateBodyImage.sqf index 62b2ebd0fb..3841f58d2e 100644 --- a/addons/medical_gui/functions/fnc_updateBodyImage.sqf +++ b/addons/medical_gui/functions/fnc_updateBodyImage.sqf @@ -20,16 +20,17 @@ params ["_ctrlGroup", "_target"]; // Get tourniquets, damage, and blood loss for target private _tourniquets = GET_TOURNIQUETS(_target); +private _fractures = GET_FRACTURES(_target); private _bodyPartDamage = _target getVariable [QEGVAR(medical,bodyPartDamage), [0, 0, 0, 0, 0, 0]]; private _bodyPartBloodLoss = [0, 0, 0, 0, 0, 0]; { - _x params ["", "", "_bodyPartN", "_amountOf", "_bleeding"]; + _x params ["", "_bodyPartN", "_amountOf", "_bleeding"]; _bodyPartBloodLoss set [_bodyPartN, (_bodyPartBloodLoss select _bodyPartN) + (_bleeding * _amountOf)]; -} forEach (_target getVariable [QEGVAR(medical,openWounds), []]); +} forEach GET_OPEN_WOUNDS(_target); { - _x params ["_bodyPartIDC", ["_tourniquetIDC", -1]]; + _x params ["_bodyPartIDC", ["_tourniquetIDC", -1], ["_fractureIDC", -1]]; // Show or hide the tourniquet icon if (_tourniquetIDC != -1) then { @@ -38,6 +39,28 @@ private _bodyPartBloodLoss = [0, 0, 0, 0, 0, 0]; _ctrlTourniquet ctrlShow _hasTourniquet; }; + // Show or hide fractrue/bones + if (_fractureIDC != -1) then { + private _ctrlBone = _ctrlGroup controlsGroupCtrl _fractureIDC; + switch (_fractures select _forEachIndex) do { + case 0: { + _ctrlBone ctrlShow false; + }; + case 1: { + _ctrlBone ctrlShow true; + _ctrlBone ctrlSetTextColor [1, 0, 0, 1]; + }; + case -1: { + if (EGVAR(medical,fractures) == 2) then { + _ctrlBone ctrlShow true; + _ctrlBone ctrlSetTextColor [0, 0, 1, 1]; + } else { + _ctrlBone ctrlShow false; + }; + }; + }; + }; + // Update body part color based on blood loss and damage private _bloodLoss = _bodyPartBloodLoss select _forEachIndex; private _bodyPartColor = if (_bloodLoss > 0) then { @@ -52,8 +75,8 @@ private _bodyPartBloodLoss = [0, 0, 0, 0, 0, 0]; } forEach [ [IDC_BODY_HEAD], [IDC_BODY_TORSO], - [IDC_BODY_ARMLEFT, IDC_BODY_ARMLEFT_T], - [IDC_BODY_ARMRIGHT, IDC_BODY_ARMRIGHT_T], - [IDC_BODY_LEGLEFT, IDC_BODY_LEGLEFT_T], - [IDC_BODY_LEGRIGHT, IDC_BODY_LEGRIGHT_T] + [IDC_BODY_ARMLEFT, IDC_BODY_ARMLEFT_T, IDC_BODY_ARMLEFT_B], + [IDC_BODY_ARMRIGHT, IDC_BODY_ARMRIGHT_T, IDC_BODY_ARMRIGHT_B], + [IDC_BODY_LEGLEFT, IDC_BODY_LEGLEFT_T, IDC_BODY_LEGLEFT_B], + [IDC_BODY_LEGRIGHT, IDC_BODY_LEGRIGHT_T, IDC_BODY_LEGRIGHT_B] ]; diff --git a/addons/medical_gui/functions/fnc_updateInjuryList.sqf b/addons/medical_gui/functions/fnc_updateInjuryList.sqf index 49966fdc4a..de5b22df3e 100644 --- a/addons/medical_gui/functions/fnc_updateInjuryList.sqf +++ b/addons/medical_gui/functions/fnc_updateInjuryList.sqf @@ -59,8 +59,20 @@ if (HAS_TOURNIQUET_APPLIED_ON(_target,_selectionN)) then { _entries pushBack [localize LSTRING(Status_Tourniquet_Applied), [0.77, 0.51, 0.08, 1]]; }; +// Indicate current body part fracture status +switch (GET_FRACTURES(_target) select _selectionN) do { + case 1: { + _entries pushBack [localize LSTRING(Status_Fractured), [1, 0, 0, 1]]; + }; + case -1: { + if (EGVAR(medical,fractures) == 2) then { // Ignore if the splint has no effect + _entries pushBack [localize LSTRING(Status_SplintApplied), [1, 1, 1, 1]]; + }; + }; +}; + // Indicate the amount of pain the unit is in -if ([_target] call EFUNC(common,isAwake)) then { +if (_target call EFUNC(common,isAwake)) then { private _pain = GET_PAIN_PERCEIVED(_target); if (_pain > 0) then { private _painText = switch (true) do { @@ -93,18 +105,20 @@ if (_totalIvVolume >= 1) then { private _woundEntries = []; private _fnc_getWoundDescription = { - private _className = EGVAR(medical_damage,woundsData) select _woundClassID select 6; + private _classIndex = _woundClassID / 10; + private _category = _woundClassID % 10; + private _className = EGVAR(medical_damage,woundsData) select _classIndex select 6; private _suffix = ["Minor", "Medium", "Large"] select _category; private _woundName = localize format [ELSTRING(medical_damage,%1_%2), _className, _suffix]; if (_amountOf >= 1) then { format ["%1x %2", ceil _amountOf, _woundName]; } else { - format ["Partial %1", _woundName]; + format [localize LSTRING(PartialX), _woundName]; }; }; { - _x params ["", "_woundClassID", "_bodyPartN", "_amountOf", "", "", "_category"]; + _x params ["_woundClassID", "_bodyPartN", "_amountOf"]; if (_selectionN == _bodyPartN) then { if (_amountOf > 0) then { _woundEntries pushBack [call _fnc_getWoundDescription, [1, 1, 1, 1]]; @@ -114,21 +128,21 @@ private _fnc_getWoundDescription = { }; }; }; -} forEach (_target getVariable [QEGVAR(medical,openWounds), []]); +} forEach GET_OPEN_WOUNDS(_target); { - _x params ["", "_woundClassID", "_bodyPartN", "_amountOf", "", "", "_category"]; + _x params ["_woundClassID", "_bodyPartN", "_amountOf"]; if (_selectionN == _bodyPartN && {_amountOf > 0}) then { _woundEntries pushBack [format ["[B] %1", call _fnc_getWoundDescription], [0.88, 0.7, 0.65, 1]]; }; -} forEach (_target getVariable [QEGVAR(medical,bandagedWounds), []]); +} forEach GET_BANDAGED_WOUNDS(_target); { - _x params ["", "_woundClassID", "_bodyPartN", "_amountOf", "", "", "_category"]; + _x params ["_woundClassID", "_bodyPartN", "_amountOf"]; if (_selectionN == _bodyPartN && {_amountOf > 0}) then { _woundEntries pushBack [format ["[S] %1", call _fnc_getWoundDescription], [0.7, 0.7, 0.7, 1]]; }; -} forEach (_target getVariable [QEGVAR(medical,stitchedWounds), []]); +} forEach GET_STITCHED_WOUNDS(_target); // Handle no wound entries if (_woundEntries isEqualTo []) then { @@ -142,7 +156,8 @@ lbClear _ctrl; { _x params ["_text", "_color"]; - private _index = _ctrl lbAdd _text; - _ctrl lbSetColor [_index, _color]; - _ctrl lbSetSelectColor [_index, _color]; + + _ctrl lbSetColor [_ctrl lbAdd _text, _color]; } forEach _entries; + +_ctrl lbSetCurSel -1; diff --git a/addons/medical_gui/functions/fnc_updateLogList.sqf b/addons/medical_gui/functions/fnc_updateLogList.sqf index 731b358796..fb83640698 100644 --- a/addons/medical_gui/functions/fnc_updateLogList.sqf +++ b/addons/medical_gui/functions/fnc_updateLogList.sqf @@ -21,7 +21,7 @@ params ["_ctrl", "_logs"]; lbClear _ctrl; { - _x params ["_message", "_moment", "", "_arguments"]; + _x params ["_message", "_timeStamp", "_arguments"]; // Localize message and arguments if (isLocalized _message) then { @@ -33,5 +33,5 @@ lbClear _ctrl; // Format message with arguments _message = format ([_message] + _arguments); - _ctrl lbAdd format ["%1 %2", _moment, _message]; + _ctrl lbAdd format ["%1 %2", _timeStamp, _message]; } forEach _logs; diff --git a/addons/medical_gui/gui.hpp b/addons/medical_gui/gui.hpp index eceb263a60..06db05ad38 100644 --- a/addons/medical_gui/gui.hpp +++ b/addons/medical_gui/gui.hpp @@ -45,6 +45,24 @@ class GVAR(BodyImage): RscControlsGroupNoScrollbars { idc = IDC_BODY_LEGRIGHT; text = QPATHTOF(data\body_image\leg_right.paa); }; + class ArmLeftB: Background { + idc = IDC_BODY_ARMLEFT_B; + text = QPATHTOF(data\body_image\arm_left_b.paa); + colorText[] = {0, 0, 0.8, 1}; + show = 0; + }; + class ArmRightB: ArmLeftB { + idc = IDC_BODY_ARMRIGHT_B; + text = QPATHTOF(data\body_image\arm_right_b.paa); + }; + class LegLeftB: ArmLeftB { + idc = IDC_BODY_LEGLEFT_B; + text = QPATHTOF(data\body_image\leg_left_b.paa); + }; + class LegRightB: ArmLeftB { + idc = IDC_BODY_LEGRIGHT_B; + text = QPATHTOF(data\body_image\leg_right_b.paa); + }; class ArmLeftT: Background { idc = IDC_BODY_ARMLEFT_T; text = QPATHTOF(data\body_image\arm_left_t.paa); @@ -549,6 +567,22 @@ class RscTitles { w = POS_W(8.5); h = POS_H(8.5); }; + class ArmLeftB: ArmLeftB { + w = POS_W(8.5); + h = POS_H(8.5); + }; + class ArmRightB: ArmRightB { + w = POS_W(8.5); + h = POS_H(8.5); + }; + class LegLeftB: LegLeftB { + w = POS_W(8.5); + h = POS_H(8.5); + }; + class LegRightB: LegRightB { + w = POS_W(8.5); + h = POS_H(8.5); + }; class ArmLeftT: ArmLeftT { w = POS_W(8.5); h = POS_H(8.5); diff --git a/addons/medical_gui/initSettings.sqf b/addons/medical_gui/initSettings.sqf index 6066d073af..be7dc60fa6 100644 --- a/addons/medical_gui/initSettings.sqf +++ b/addons/medical_gui/initSettings.sqf @@ -2,7 +2,7 @@ QGVAR(enableActions), "LIST", [LSTRING(EnableActions_DisplayName), LSTRING(EnableActions_Description)], - LSTRING(Category), + [ELSTRING(medical,Category), LSTRING(SubCategory)], [[0, 1, 2], [LSTRING(Selections3D), LSTRING(Radial), ELSTRING(common,Disabled)], 0], false ] call CBA_settings_fnc_init; @@ -11,7 +11,7 @@ QGVAR(enableSelfActions), "CHECKBOX", [LSTRING(EnableSelfActions_DisplayName), LSTRING(EnableSelfActions_Description)], - LSTRING(Category), + [ELSTRING(medical,Category), LSTRING(SubCategory)], true, false ] call CBA_settings_fnc_init; @@ -20,7 +20,7 @@ QGVAR(enableMedicalMenu), "LIST", [LSTRING(EnableMedicalMenu_DisplayName), LSTRING(EnableMedicalMenu_Description)], - LSTRING(Category), + [ELSTRING(medical,Category), LSTRING(SubCategory)], [[0, 1, 2], [ELSTRING(common,Disabled), ELSTRING(common,Enabled), ELSTRING(common,VehiclesOnly)], 1], false ] call CBA_settings_fnc_init; @@ -29,7 +29,7 @@ QGVAR(openAfterTreatment), "CHECKBOX", [LSTRING(OpenAfterTreatment_DisplayName), LSTRING(OpenAfterTreatment_Description)], - LSTRING(Category), + [ELSTRING(medical,Category), LSTRING(SubCategory)], true, false ] call CBA_settings_fnc_init; @@ -38,7 +38,7 @@ QGVAR(maxDistance), "SLIDER", [LSTRING(MaxDistance_DisplayName), LSTRING(MaxDistance_Description)], - LSTRING(Category), + [ELSTRING(medical,Category), LSTRING(SubCategory)], [0, 10, 3, 1], - false + true ] call CBA_settings_fnc_init; diff --git a/addons/medical_gui/script_component.hpp b/addons/medical_gui/script_component.hpp index a1c8fb6a8d..04565dc5b6 100644 --- a/addons/medical_gui/script_component.hpp +++ b/addons/medical_gui/script_component.hpp @@ -67,6 +67,10 @@ #define IDC_BODY_ARMRIGHT_T 6040 #define IDC_BODY_LEGLEFT_T 6045 #define IDC_BODY_LEGRIGHT_T 6050 +#define IDC_BODY_ARMLEFT_B 6055 +#define IDC_BODY_ARMRIGHT_B 6060 +#define IDC_BODY_LEGLEFT_B 6065 +#define IDC_BODY_LEGRIGHT_B 6070 #define IDC_TRIAGE_STATUS 7000 #define IDC_TRIAGE_SELECT 7100 diff --git a/addons/medical_gui/stringtable.xml b/addons/medical_gui/stringtable.xml index 3359f08bd5..9b75348210 100644 --- a/addons/medical_gui/stringtable.xml +++ b/addons/medical_gui/stringtable.xml @@ -1,14 +1,28 @@ - - ACE Medical GUI + + GUI + GUI + GUI + Медицинский интерфейс + GUI Enable Medical Actions + Aktiviere Sanitätsaktionen + 医療行為を有効化 + Разрешить Медицинские действия + Activer actions médicales + Ativar Ações Médicas 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, ainsi que de choisir le style visuel. + Ativa as ações médicas para o menu de interação e seleciona seus estilos. Selections (3D) @@ -21,7 +35,7 @@ Választékok (3D) 3D výběr Selezione (3D) - 選択 (3d) + 選択 (3D) 선택 (3d) 选择 (3D) 選擇 (3D) @@ -44,27 +58,67 @@ Enable Medical Self Actions + Medizinische Selbst-Interaktionen anzeigen + 自分への医療行為を有効化 + Разрешить Медицинские действия на себе + Activer actions médicales sur soi-même + Ativar ações médicas em si mesmo 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. Enable Medical Menu + Aktiviere das Sanitätsmenü + 医療メニューを有効化 + Разрешить Медицинское меню + Activer menu médical + Ativar Menu Médico 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 une touche, ou via le menu d'interaction. + Ativa o uso do Menu Médico atráves da Tecla ou Menu de Interação. Reopen Medical Menu + Sanitätsmenü wieder öffnen + 医療メニューの再使用 + Открывать меню после лечения + Rouvrir le menu médical + Reabrir Menu Médico 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 Maximum Distance + Maximale Entfernung + 最大距離 + Макс. дистанция + Distance maximale + Distância Máxima 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. Medical @@ -86,7 +140,7 @@ Medical Menu Sanitätsmenü Menu medyczne - Menu médico + Menu Médico Медицинское меню Menú médico Zdravotnikcá nabídka @@ -107,7 +161,7 @@ Otevřít zdravotnickou nabídku Apri Menù Medico Ouvir le menu médical - 治療メニューをひらく + 治療メニューを開く 의료 메뉴 열기 开起医疗选单 開起醫療選單 @@ -134,7 +188,7 @@ Выгрузить пациента Patient ausladen Wyładuj pacjenta - Le patient débarque + Débarquer le patient Sebesült kihúzása Scarica il paziente Descarregar Paciente @@ -240,7 +294,7 @@ Zeige Triagekarte Смотреть первичную карточку Ver Triage - Voir Carte de Triage + Voir Fiche de Triage Pokaż kartę segregacyjną Ver cartão de triagem Zkontrolovat štítek @@ -335,7 +389,7 @@ Arrastar / Carregar Táhnout / Nést Trascina / Trasporta - 引きずる / 運ぶ + 引きずる / 担ぐ 끌기 / 들기 拖 / 背 拖 / 背 @@ -344,7 +398,7 @@ Toggle (Self) Umschalter (Selbst) Лечить себя/другого раненого - Basculer (soi) + Basculer (soi-même) Przełącz (na siebie) Alternar Alternar (Si mesmo) @@ -585,7 +639,7 @@ Er hat %2 offene Wunden (%1) %2 открытые раны %1 Hay %2 Heridas Abiertas %1 - Il y a %2 %1 blessure(s) ouverte(s) + Il y a %2 blessures ouvertes (%1) Widzisz otwarte rany w ilości %2 o %1 rozmiarze Existem %2 ferimentos abertos %1 Jsou zde %2 %1 otevřené rány @@ -600,7 +654,7 @@ Er hat 1 offene Wunde (%1) Открытая рана %1 Hay 1 Herida Abierta %1 - Il y a 1 blessure ouverte %1 + Il y a 1 blessure ouverte (%1) Widzisz 1 otwartą ranę o %1 rozmiarze Existe 1 %1 ferimento aberto Je zde 1 %1 otevřená rána @@ -615,7 +669,7 @@ Er hat eine zum Teil offene Wunde (%1) Частично открытая рана %1 Hay una herida parcial abierta %1 - Il y a une blessure partiellement ouverte %1 + Il y a une blessure partiellement ouverte (%1) Widzisz częściowo otwartą ranę o %1 rozmiarze Existe um ferimento parcial aberto %1 Je zde částečně %1 otevřená rána @@ -630,7 +684,7 @@ Er hat %2 verbundene Wunden (%1) %2 перевязанные раны %1 Hay %2 Heridas %1 Vendadas - Il y a %2 %1 blessure(s) bandée(s) + Il y a %2 blessures pansées (%1) Widzisz %2 zabandażowanych ran o %1 rozmiarze Existem %2 ferimentos %1 tratados Jsou zde %2 %1 ovázané rány @@ -645,7 +699,7 @@ Er hat 1 verbundene Wunde (%1) 1 перевязанная рана %1 Hay 1 Herida Vendada %1 - Il y a 1 %1 blessure bandée + Il y a 1 blessure pansée (%1) Widzisz 1 zabandażowaną ranę o %1 rozmiarze Existe 1 ferimento %1 tratado Je zde 1 %1 ovázaná rána @@ -660,7 +714,7 @@ Er hat eine zum Teil verbundene Wunde (%1) Частично перевязанная рана %1 Hay una Herida parcial %1 Vendada - Il y a %1 blessure partiellement bandée + Il y a 1 blessure partiellement bandée (%1) 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 @@ -720,7 +774,7 @@ Beinahe keine Atmung Дыхания почти нет Casi sin respirar - Respiration faible + Respiration très faible Prawie brak oddechu Quase sem respiração Téměř nedýchá @@ -775,11 +829,30 @@ 大量失血 大量失血 + + Fractured + Перелом + 骨折している + Fracturé + Fraturado + + + Splint Applied + Наложена шина + 添え木が当てている + Attelle appliquée + Tala Aplicada + Lost some blood + Hat etwas Blut verloren + いくらか失血している + Небольшая кровопотеря + A perdu un peu de sang + Perdeu um pouco de Sangue Lost a lot of blood @@ -799,9 +872,19 @@ Lost a large amount of blood + Hat eine sehr große Menge Blut verloren + かなり酷く大量失血している + Огромная кровопотеря + A perdu une grande quantité de sang + Perdeu uma quantidade grande de sangue Lost a fatal amount of blood + Hat eine kritische Menge an Blut verloren + 致命的な程失血している + Фатальная кровопотеря + Exsanguination + Perdeu uma quantidade fatal de sangue Tourniquet [CAT] @@ -823,7 +906,7 @@ Nasen-Rachen-Rohr Назотрахеальная трубка Torniquete [CAT] - Canule Naseaupharyngée [NPA] + Canule Nasopharyngée [NPA] Rurka nosowo-gardłowa [NPA] Tubo nasofaríngeo [NPA] Nasofaryngeální trubice [NPA] @@ -849,5 +932,8 @@ 检伤分类卡 檢傷分類卡 + + Partial %1 + diff --git a/addons/medical_gui/ui/splint.paa b/addons/medical_gui/ui/splint.paa new file mode 100644 index 0000000000..8cd9866d5e Binary files /dev/null and b/addons/medical_gui/ui/splint.paa differ diff --git a/addons/medical_statemachine/ACE_Settings.hpp b/addons/medical_statemachine/ACE_Settings.hpp deleted file mode 100644 index 8b47bd106d..0000000000 --- a/addons/medical_statemachine/ACE_Settings.hpp +++ /dev/null @@ -1,14 +0,0 @@ -class ACE_Settings { - class GVAR(fatalInjuryCondition) { - movedToSQF = 1; - }; - class GVAR(fatalInjuryConditionAI) { - movedToSQF = 1; - }; - class GVAR(unconsciousConditionAI) { - movedToSQF = 1; - }; - class GVAR(cardiacArrestTime) { - movedToSQF = 1; - }; -}; diff --git a/addons/medical_statemachine/CfgEventHandlers.hpp b/addons/medical_statemachine/CfgEventHandlers.hpp index f0de7ed461..7196bf8aaf 100644 --- a/addons/medical_statemachine/CfgEventHandlers.hpp +++ b/addons/medical_statemachine/CfgEventHandlers.hpp @@ -10,16 +10,20 @@ class Extended_PreInit_EventHandlers { }; }; -class Extended_PostInit_EventHandlers { - class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); - }; -}; - class Extended_Respawn_EventHandlers { class CAManBase { class ADDON { respawn = QUOTE(call FUNC(resetStateDefault)); + exclude[] = {IGNORE_BASE_UAVPILOTS}; + }; + }; +}; + +class Extended_Local_EventHandlers { + class CAManBase { + class ADDON { + local = QUOTE(call FUNC(localityChangedEH)); + exclude[] = {IGNORE_BASE_UAVPILOTS}; }; }; }; diff --git a/addons/medical_statemachine/Statemachine.hpp b/addons/medical_statemachine/Statemachine.hpp index 12a5a01779..17a4baaf07 100644 --- a/addons/medical_statemachine/Statemachine.hpp +++ b/addons/medical_statemachine/Statemachine.hpp @@ -3,7 +3,6 @@ class ACE_Medical_StateMachine { list = QUOTE(call EFUNC(common,getLocalUnits)); skipNull = 1; - class Default { onState = QFUNC(handleStateDefault); class Injury { @@ -44,16 +43,16 @@ class ACE_Medical_StateMachine { }; class Unconscious { onState = QFUNC(handleStateUnconscious); - onStateEntered = QUOTE([ARR_2(_this,(true))] call EFUNC(medical_status,setUnconscious)); + onStateEntered = QUOTE([ARR_2(_this,true)] call EFUNC(medical_status,setUnconsciousState)); class DeathAI { targetState = "Dead"; - condition = QUOTE(!isPlayer _this && {GVAR(unconsciousConditionAI)}); + condition = QUOTE(!GVAR(AIUnconsciousness) && {!isPlayer _this}); }; class WakeUp { targetState = "Injured"; condition = QEFUNC(medical_status,hasStableVitals); events[] = {QEGVAR(medical,WakeUp)}; - onTransition = QUOTE([ARR_2(_this,(false))] call EFUNC(medical_status,setUnconscious)); + onTransition = QUOTE([ARR_2(_this,false)] call EFUNC(medical_status,setUnconsciousState)); }; class FatalTransitions { targetState = "CardiacArrest"; @@ -65,32 +64,29 @@ class ACE_Medical_StateMachine { }; }; class FatalInjury { - // Transition state for handling instant death + // Transition state for handling instant death from fatal injuries // This state raises the next transition in the same frame onStateEntered = QFUNC(enteredStateFatalInjury); - class DeathAI { - events[] = {QEGVAR(medical,FatalInjuryInstantTransition)}; - targetState = "Dead"; - condition = QUOTE(!isPlayer _this && {GVAR(fatalInjuryConditionAI)}); - }; class SecondChance { events[] = {QEGVAR(medical,FatalInjuryInstantTransition)}; targetState = "CardiacArrest"; - condition = QUOTE(GVAR(fatalInjuryCondition) > 0); + condition = QFUNC(conditionSecondChance); onTransition = QFUNC(transitionSecondChance); }; class Death { events[] = {QEGVAR(medical,FatalInjuryInstantTransition)}; targetState = "Dead"; - condition = "true"; }; }; class CardiacArrest { + onState = QFUNC(handleStateCardiacArrest); onStateEntered = QFUNC(enteredStateCardiacArrest); onStateLeaving = QFUNC(leftStateCardiacArrest); class DeathAI { + // If an AI unit reanimates, they will immediately die upon entering unconsciousness if AI Unconsciousness is disabled + // As a result, we immediately kill the AI unit since cardiac arrest is effectively useless for it targetState = "Dead"; - condition = QUOTE(!isPlayer _this && {GVAR(fatalInjuryConditionAI)}); + condition = QUOTE(!GVAR(AIUnconsciousness) && {!isPlayer _this}); }; class Timeout { targetState = "Dead"; diff --git a/addons/medical_statemachine/XEH_PREP.hpp b/addons/medical_statemachine/XEH_PREP.hpp index e2e27963b1..38d0cb573a 100644 --- a/addons/medical_statemachine/XEH_PREP.hpp +++ b/addons/medical_statemachine/XEH_PREP.hpp @@ -1,11 +1,14 @@ PREP(conditionCardiacArrestTimer); PREP(conditionExecutionDeath); +PREP(conditionSecondChance); PREP(enteredStateCardiacArrest); PREP(enteredStateDeath); PREP(enteredStateFatalInjury); +PREP(handleStateCardiacArrest); PREP(handleStateDefault); PREP(handleStateInjured); PREP(handleStateUnconscious); PREP(leftStateCardiacArrest); +PREP(localityChangedEH); PREP(resetStateDefault); PREP(transitionSecondChance); diff --git a/addons/medical_statemachine/XEH_preInit.sqf b/addons/medical_statemachine/XEH_preInit.sqf index 2d8754ad32..d77d8067a8 100644 --- a/addons/medical_statemachine/XEH_preInit.sqf +++ b/addons/medical_statemachine/XEH_preInit.sqf @@ -2,7 +2,9 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; #include "initSettings.sqf" diff --git a/addons/medical_statemachine/config.cpp b/addons/medical_statemachine/config.cpp index a87d797163..23a55f5258 100644 --- a/addons/medical_statemachine/config.cpp +++ b/addons/medical_statemachine/config.cpp @@ -14,6 +14,5 @@ class CfgPatches { }; }; -#include "ACE_Settings.hpp" #include "Statemachine.hpp" #include "CfgEventHandlers.hpp" diff --git a/addons/medical_statemachine/functions/fnc_conditionCardiacArrestTimer.sqf b/addons/medical_statemachine/functions/fnc_conditionCardiacArrestTimer.sqf index df29c592a1..b28459db53 100644 --- a/addons/medical_statemachine/functions/fnc_conditionCardiacArrestTimer.sqf +++ b/addons/medical_statemachine/functions/fnc_conditionCardiacArrestTimer.sqf @@ -17,7 +17,4 @@ params ["_unit"]; -private _startTime = _unit getVariable [QGVAR(cardiacArrestStart), CBA_missionTime]; -private _lifeTime = _unit getVariable [QGVAR(cardiacArrestTime), GVAR(cardiacArrestTime)]; - -(CBA_missionTime - _startTime) > _lifeTime +(_unit getVariable [QGVAR(cardiacArrestTimeLeft), -1]) <= 0 diff --git a/addons/medical_statemachine/functions/fnc_conditionExecutionDeath.sqf b/addons/medical_statemachine/functions/fnc_conditionExecutionDeath.sqf index a409069fba..26ff20c42a 100644 --- a/addons/medical_statemachine/functions/fnc_conditionExecutionDeath.sqf +++ b/addons/medical_statemachine/functions/fnc_conditionExecutionDeath.sqf @@ -1,10 +1,10 @@ #include "script_component.hpp" /* * Author: BaerMitUmlaut - * Condition for an execution caused death. + * Condition for an execution caused death (fatal injury received in cardiac arrest). * * Arguments: - * 0: The Unit + * 0: Unit * * Return Value: * None @@ -17,4 +17,9 @@ params ["_unit"]; -(GVAR(fatalInjuryCondition) < 2) && {!(_unit getVariable [QEGVAR(medical,deathBlocked), false])} +(if (isPlayer _unit) then { + GVAR(fatalInjuriesPlayer) != FATAL_INJURIES_NEVER +} else { + GVAR(fatalInjuriesAI) != FATAL_INJURIES_NEVER +}) +&& {!(_unit getVariable [QEGVAR(medical,deathBlocked), false])} diff --git a/addons/medical_statemachine/functions/fnc_conditionSecondChance.sqf b/addons/medical_statemachine/functions/fnc_conditionSecondChance.sqf new file mode 100644 index 0000000000..660ea84ac1 --- /dev/null +++ b/addons/medical_statemachine/functions/fnc_conditionSecondChance.sqf @@ -0,0 +1,24 @@ +#include "script_component.hpp" +/* + * Author: mharis001 + * Condition for going into cardiac arrest upon receiving a fatal injury. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * [player] call ace_medical_statemachine_fnc_conditionSecondChance + * + * Public: No + */ + +params ["_unit"]; + +if (isPlayer _unit) then { + GVAR(fatalInjuriesPlayer) != FATAL_INJURIES_ALWAYS +} else { + GVAR(fatalInjuriesAI) != FATAL_INJURIES_ALWAYS +} diff --git a/addons/medical_statemachine/functions/fnc_enteredStateCardiacArrest.sqf b/addons/medical_statemachine/functions/fnc_enteredStateCardiacArrest.sqf index f418e38b84..b2bcde8071 100644 --- a/addons/medical_statemachine/functions/fnc_enteredStateCardiacArrest.sqf +++ b/addons/medical_statemachine/functions/fnc_enteredStateCardiacArrest.sqf @@ -20,10 +20,12 @@ params ["_unit"]; // 10% possible variance in cardiac arrest time private _time = GVAR(cardiacArrestTime); -_time = _time + random [_time*-0.1, 0, _time*0.1]; +_time = _time + _time * random [-0.1, 0, 0.1]; -_unit setVariable [QGVAR(cardiacArrestTime), _time]; -_unit setVariable [QGVAR(cardiacArrestStart), CBA_missionTime]; +_unit setVariable [QGVAR(cardiacArrestTimeLeft), _time]; +_unit setVariable [QGVAR(cardiacArrestTimeLastUpdate), CBA_missionTime]; + +TRACE_3("enteredStateCardiacArrest",_unit,_time,CBA_missionTime); // Update the unit status to reflect cardiac arrest -[_unit, true] call EFUNC(medical_status,setCardiacArrest); +[_unit, true] call EFUNC(medical_status,setCardiacArrestState); diff --git a/addons/medical_statemachine/functions/fnc_enteredStateDeath.sqf b/addons/medical_statemachine/functions/fnc_enteredStateDeath.sqf index d99d13faca..cb6f63c39a 100644 --- a/addons/medical_statemachine/functions/fnc_enteredStateDeath.sqf +++ b/addons/medical_statemachine/functions/fnc_enteredStateDeath.sqf @@ -16,10 +16,12 @@ */ params ["_unit"]; +if (isNull _unit) exitWith {}; -// TODO: Probably also needs additional logic to deal with edge cases +//IGNORE_PRIVATE_WARNING ["_thisOrigin", "_thisTransition"]; // vars provided by CBA_statemachine +TRACE_3("enteredStateDeath",_this,_thisOrigin,_thisTransition); -// Send a local event before death -[QEGVAR(medical,death), [_unit]] call CBA_fnc_localEvent; +private _causeOfDeath = format ["%1:%2", _thisOrigin, _thisTransition]; -[_unit] call EFUNC(medical_status,setDead); +// could delay a frame here to fix the double killed EH, but we lose it being a "native" kill (scoreboard / rating) +[_unit, _causeOfDeath] call EFUNC(medical_status,setDead); diff --git a/addons/medical_statemachine/functions/fnc_handleStateCardiacArrest.sqf b/addons/medical_statemachine/functions/fnc_handleStateCardiacArrest.sqf new file mode 100644 index 0000000000..b9e49adfe3 --- /dev/null +++ b/addons/medical_statemachine/functions/fnc_handleStateCardiacArrest.sqf @@ -0,0 +1,37 @@ +#include "script_component.hpp" +/* + * Author: BaerMitUmlaut + * Handles the unconscious state + * + * Arguments: + * 0: The Unit + * + * Return Value: + * None + * + * Example: + * [player] call ace_medical_statemachine_fnc_handleStateCardiacArrest + * + * Public: No + */ + +params ["_unit"]; + +// If the unit died the loop is finished +if (!alive _unit) exitWith {}; +if (!local _unit) exitWith {}; + +[_unit] call EFUNC(medical_vitals,handleUnitVitals); + +private _timeDiff = CBA_missionTime - (_unit getVariable [QGVAR(cardiacArrestTimeLastUpdate), 0]); +if (_timeDiff >= 1) then { + _timeDiff = _timeDiff min 10; + _unit setVariable [QGVAR(cardiacArrestTimeLastUpdate), CBA_missionTime]; + private _recieveingCPR = alive (_unit getVariable [QEGVAR(medical,CPR_provider), objNull]); + private _timeLeft = _unit getVariable [QGVAR(cardiacArrestTimeLeft), -1]; + TRACE_3("cardiac arrest life tick",_unit,_recieveingCPR,_timeDiff); + if (_recieveingCPR) then { _timeDiff = _timeDiff * 0.5; }; // if being cpr'ed, then time decrease is reduced + _timeLeft = _timeLeft - _timeDiff; // negative values are fine + _unit setVariable [QGVAR(cardiacArrestTimeLeft), _timeLeft]; +}; + diff --git a/addons/medical_statemachine/functions/fnc_handleStateDefault.sqf b/addons/medical_statemachine/functions/fnc_handleStateDefault.sqf index 34187fca28..33cb1d29c0 100644 --- a/addons/medical_statemachine/functions/fnc_handleStateDefault.sqf +++ b/addons/medical_statemachine/functions/fnc_handleStateDefault.sqf @@ -19,13 +19,7 @@ params ["_unit"]; // If the unit died the loop is finished if (!alive _unit) exitWith {}; - -// If locality changed, broadcast the last medical state and finish the local loop -if (!local _unit) exitWith { - _unit setVariable [VAR_HEART_RATE, GET_HEART_RATE(_unit), true]; - _unit setVariable [VAR_BLOOD_PRESS, _unit getVariable [VAR_BLOOD_PRESS, [80, 120]], true]; - _unit setVariable [VAR_BLOOD_VOL, GET_BLOOD_VOLUME(_unit), true]; -}; +if (!local _unit) exitWith {}; [_unit] call EFUNC(medical_vitals,handleUnitVitals); diff --git a/addons/medical_statemachine/functions/fnc_handleStateInjured.sqf b/addons/medical_statemachine/functions/fnc_handleStateInjured.sqf index a75397c876..50f4a6bfa6 100644 --- a/addons/medical_statemachine/functions/fnc_handleStateInjured.sqf +++ b/addons/medical_statemachine/functions/fnc_handleStateInjured.sqf @@ -19,13 +19,7 @@ params ["_unit"]; // If the unit died the loop is finished if (!alive _unit) exitWith {}; - -// If locality changed, broadcast the last medical state and finish the local loop -if (!local _unit) exitWith { - _unit setVariable [VAR_HEART_RATE, GET_HEART_RATE(_unit), true]; - _unit setVariable [VAR_BLOOD_PRESS, _unit getVariable [VAR_BLOOD_PRESS, [80, 120]], true]; - _unit setVariable [VAR_BLOOD_VOL, GET_BLOOD_VOLUME(_unit), true]; -}; +if (!local _unit) exitWith {}; [_unit] call EFUNC(medical_vitals,handleUnitVitals); diff --git a/addons/medical_statemachine/functions/fnc_handleStateUnconscious.sqf b/addons/medical_statemachine/functions/fnc_handleStateUnconscious.sqf index fdb730c0bf..5fb94333c2 100644 --- a/addons/medical_statemachine/functions/fnc_handleStateUnconscious.sqf +++ b/addons/medical_statemachine/functions/fnc_handleStateUnconscious.sqf @@ -18,14 +18,7 @@ params ["_unit"]; // If the unit died the loop is finished -if (!alive _unit) exitWith {}; - -// If locality changed, broadcast the last medical state and finish the local loop -if (!local _unit) exitWith { - _unit setVariable [VAR_HEART_RATE, GET_HEART_RATE(_unit), true]; - _unit setVariable [VAR_BLOOD_PRESS, _unit getVariable [VAR_BLOOD_PRESS, [80, 120]], true]; - _unit setVariable [VAR_BLOOD_VOL, GET_BLOOD_VOLUME(_unit), true]; -}; +if (!alive _unit || {!local _unit}) exitWith {}; [_unit] call EFUNC(medical_vitals,handleUnitVitals); @@ -34,20 +27,36 @@ if (_painLevel > 0) then { [QEGVAR(medical,moan), [_unit, _painLevel]] call CBA_fnc_localEvent; }; -// Handle spontaneous wakeup from unconsciousness +// Handle spontaneous wake up from unconsciousness if (EGVAR(medical,spontaneousWakeUpChance) > 0) then { if (_unit call EFUNC(medical_status,hasStableVitals)) then { - private _lastWakeUpCheck = _unit getVariable [QEGVAR(medical,lastWakeUpCheck), CBA_missionTime]; - if (CBA_missionTime - _lastWakeUpCheck > SPONTANEOUS_WAKE_UP_INTERVAL) then { + private _lastWakeUpCheck = _unit getVariable QEGVAR(medical,lastWakeUpCheck); + + // Handle setting being changed mid-mission and still properly check + // already unconscious units, should handle locality changes as well + if (isNil "_lastWakeUpCheck") exitWith { + TRACE_1("undefined lastWakeUpCheck: setting to current time",_lastWakeUpCheck); + _unit setVariable [QEGVAR(medical,lastWakeUpCheck), CBA_missionTime]; + }; + + private _wakeUpCheckInterval = SPONTANEOUS_WAKE_UP_INTERVAL; + if (EGVAR(medical,spontaneousWakeUpEpinephrineBoost) > 1) then { + private _epiEffectiveness = [_unit, "Epinephrine", false] call EFUNC(medical_status,getMedicationCount); + _wakeUpCheckInterval = _wakeUpCheckInterval * linearConversion [0, 1, _epiEffectiveness, 1, 1 / EGVAR(medical,spontaneousWakeUpEpinephrineBoost), true]; + TRACE_2("epiBoost",_epiEffectiveness,_wakeUpCheckInterval); + }; + if (CBA_missionTime - _lastWakeUpCheck > _wakeUpCheckInterval) then { TRACE_2("Checking for wake up",_unit,EGVAR(medical,spontaneousWakeUpChance)); _unit setVariable [QEGVAR(medical,lastWakeUpCheck), CBA_missionTime]; - if ((random 1) < EGVAR(medical,spontaneousWakeUpChance)) then { + + if (random 1 <= EGVAR(medical,spontaneousWakeUpChance)) then { TRACE_1("Spontaneous wake up!",_unit); [QEGVAR(medical,WakeUp), _unit] call CBA_fnc_localEvent; }; }; } else { // Unstable vitals, procrastinate the next wakeup check - _unit setVariable [QEGVAR(medical,lastWakeUpCheck), CBA_missionTime]; + private _lastWakeUpCheck = _unit getVariable [QEGVAR(medical,lastWakeUpCheck), 0]; + _unit setVariable [QEGVAR(medical,lastWakeUpCheck), _lastWakeUpCheck max CBA_missionTime]; }; }; diff --git a/addons/medical_statemachine/functions/fnc_leftStateCardiacArrest.sqf b/addons/medical_statemachine/functions/fnc_leftStateCardiacArrest.sqf index 85c469c4a5..2f0793f7c7 100644 --- a/addons/medical_statemachine/functions/fnc_leftStateCardiacArrest.sqf +++ b/addons/medical_statemachine/functions/fnc_leftStateCardiacArrest.sqf @@ -17,11 +17,9 @@ */ params ["_unit"]; +TRACE_1("leftStateCardiacArrest",_unit); -_unit setVariable [QGVAR(cardiacArrestTime), nil]; -_unit setVariable [QEGVAR(medical,cardiacArrestStart), nil]; +_unit setVariable [QGVAR(cardiacArrestTimeLeft), nil]; +_unit setVariable [QGVAR(cardiacArrestTimeLastUpdate), nil]; -// Temporary fix for vitals loop on cardiac arrest exit -_unit setVariable [QGVAR(lastTimeUpdated), CBA_missionTime]; - -[_unit, false] call EFUNC(medical_status,setCardiacArrest); +[_unit, false] call EFUNC(medical_status,setCardiacArrestState); diff --git a/addons/medical_statemachine/functions/fnc_localityChangedEH.sqf b/addons/medical_statemachine/functions/fnc_localityChangedEH.sqf new file mode 100644 index 0000000000..9e5fb3c9b5 --- /dev/null +++ b/addons/medical_statemachine/functions/fnc_localityChangedEH.sqf @@ -0,0 +1,69 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Handles locality switch. Will also be called at unit init. + * Because state machine state is local only, when a unit transfers locality we need to manually transition to it's current state + * + * Arguments: + * 0: Unit + * 1: isLocal + * + * Return Value: + * None + * + * Example: + * [player, true] call ace_medical_statemachine_fnc_localityChangedEH + * + * Public: No + */ + +params ["_unit", "_isLocal"]; +TRACE_2("localityChangedEH",_unit,_isLocal); + +if (!alive _unit) exitWith {}; + +if (_isLocal) then { + private _currentState = [_unit, EGVAR(medical,STATE_MACHINE)] call CBA_statemachine_fnc_getCurrentState; + TRACE_1("local",_currentState); + + switch (true) do { + case (IN_CRDC_ARRST(_unit)): { + if (_currentState == "CardiacArrest") exitWith {}; + _unit setVariable [VAR_CRDC_ARRST, false]; // force reset vars so setCardiacArrestState can run (enteredStateCardiacArrest will also be called) + _unit setVariable [VAR_UNCON, false]; + TRACE_1("manually changing state to CardiacArrest",_currentState); + [_unit, EGVAR(medical,STATE_MACHINE), _currentState, "CardiacArrest", {}, "LocalityChange"] call CBA_statemachine_fnc_manualTransition; + }; + case (IS_UNCONSCIOUS(_unit)): { + if (_currentState == "Unconscious") exitWith {}; + _unit setVariable [VAR_UNCON, false]; // force reset var so ace_medical_status_fnc_setUnconsciousState can run + TRACE_1("manually changing state to Unconscious",_currentState); + [_unit, EGVAR(medical,STATE_MACHINE), _currentState, "Unconscious", {}, "LocalityChange"] call CBA_statemachine_fnc_manualTransition; + }; + case (IS_BLEEDING(_unit) || {IS_IN_PAIN(_unit)}): { + if (_currentState == "Injured") exitWith {}; + TRACE_1("manually changing state to Injured",_currentState); + [_unit, EGVAR(medical,STATE_MACHINE), _currentState, "Injured", {}, "LocalityChange"] call CBA_statemachine_fnc_manualTransition; + }; + default { + // If locality transfers back and forth, we could be in an old state and should transfer back to default + if (_currentState == "Default") exitWith {}; + TRACE_1("manually changing state to Default",_currentState); + [_unit, EGVAR(medical,STATE_MACHINE), _currentState, "Default", {}, "LocalityChange"] call CBA_statemachine_fnc_manualTransition; + }; + }; +} else { + /* + // Not sure if this is even needed, idea is that on locality transfer we broadcast more up to date info + + private _lastTimeUpdated = _unit getVariable [QEGVAR(medical_vitals,lastTimeUpdated), 1e99]; + private _deltaT = CBA_missionTime - _lastTimeUpdated; + TRACE_1("not local",_deltaT); + if (_deltaT < 5) then { + // If locality changed and we have recently updated vitals, broadcast globally now + _unit setVariable [VAR_HEART_RATE, GET_HEART_RATE(_unit), true]; + _unit setVariable [VAR_BLOOD_PRESS, _unit getVariable [VAR_BLOOD_PRESS, [80, 120]], true]; + _unit setVariable [VAR_BLOOD_VOL, GET_BLOOD_VOLUME(_unit), true]; + }; + */ +}; diff --git a/addons/medical_statemachine/initSettings.sqf b/addons/medical_statemachine/initSettings.sqf index 268902a0f1..a47fa9c31b 100644 --- a/addons/medical_statemachine/initSettings.sqf +++ b/addons/medical_statemachine/initSettings.sqf @@ -1,43 +1,43 @@ -// CBA Settings [ADDON: ace_medical_statemachine]: - -private _categoryArray = [LELSTRING(medical,Category_DisplayName), LLSTRING(subCategory)]; - [ - QGVAR(fatalInjuryCondition), "LIST", - [LSTRING(fatalInjuryCondition_DisplayName), LSTRING(fatalInjuryCondition_Description)], - _categoryArray, - [[0,1,2],["Always","In Cardiac Arrest","Never"],0], // [values, titles, defaultIndex] //ToDo: Localize - true, // isGlobal - {[QGVAR(fatalInjuryCondition), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(fatalInjuriesPlayer), + "LIST", + [LSTRING(FatalInjuriesPlayer_DisplayName), LSTRING(FatalInjuriesPlayer_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], + [ + [FATAL_INJURIES_ALWAYS, FATAL_INJURIES_CRDC_ARRST, FATAL_INJURIES_NEVER], + [ELSTRING(common,Always), LSTRING(InCardiacArrest), ELSTRING(common,Never)], + 0 + ], + true ] call CBA_settings_fnc_init; [ - QGVAR(fatalInjuryConditionAI), "CHECKBOX", - [LSTRING(fatalInjuryConditionAI_DisplayName), LSTRING(fatalInjuryConditionAI_Description)], - _categoryArray, - true, // default value - true, // isGlobal - {[QGVAR(fatalInjuryConditionAI), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(fatalInjuriesAI), + "LIST", + [LSTRING(FatalInjuriesAI_DisplayName), LSTRING(FatalInjuriesAI_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], + [ + [FATAL_INJURIES_ALWAYS, FATAL_INJURIES_CRDC_ARRST, FATAL_INJURIES_NEVER], + [ELSTRING(common,Always), LSTRING(InCardiacArrest), ELSTRING(common,Never)], + 0 + ], + true ] call CBA_settings_fnc_init; [ - QGVAR(unconsciousConditionAI), "CHECKBOX", - [LSTRING(unconsciousConditionAI_DisplayName), LSTRING(unconsciousConditionAI_Description)], - _categoryArray, - true, // default value - true, // isGlobal - {[QGVAR(unconsciousConditionAI), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(AIUnconsciousness), + "CHECKBOX", + [LSTRING(AIUnconsciousness_DisplayName), LSTRING(AIUnconsciousness_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], + true, + true ] call CBA_settings_fnc_init; [ - QGVAR(cardiacArrestTime), "SLIDER", - [LSTRING(cardiacArrestTime_DisplayName), LSTRING(cardiacArrestTime_Description)], - _categoryArray, - [1,3600,30,0], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(cardiacArrestTime), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(cardiacArrestTime), + "TIME", + [LSTRING(CardiacArrestTime_DisplayName), LSTRING(CardiacArrestTime_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], + [1, 3600, 30], + true ] call CBA_settings_fnc_init; diff --git a/addons/medical_statemachine/script_component.hpp b/addons/medical_statemachine/script_component.hpp index fbde60be72..82ee57e12a 100644 --- a/addons/medical_statemachine/script_component.hpp +++ b/addons/medical_statemachine/script_component.hpp @@ -16,3 +16,7 @@ #include "\z\ace\addons\medical_engine\script_macros_medical.hpp" #include "\z\ace\addons\main\script_macros.hpp" + +#define FATAL_INJURIES_ALWAYS 0 +#define FATAL_INJURIES_CRDC_ARRST 1 +#define FATAL_INJURIES_NEVER 2 diff --git a/addons/medical_statemachine/stringtable.xml b/addons/medical_statemachine/stringtable.xml index 96f9ac93ad..aada8b5369 100644 --- a/addons/medical_statemachine/stringtable.xml +++ b/addons/medical_statemachine/stringtable.xml @@ -1,69 +1,72 @@ - - - States - - - Fatal Injury Player - - - Defines when Player can receive a fatal injury - - - Instant death AI - - - Defines if AI will be able to die instantly - - - Forbid unconscious AI - - - Defines if AI will be denied to go unconscious and will die instead - - - In Cardiac Arrest - - - Cardiac Arrest time (seconds) - - - Defines how long it takes to die from cardiac arrest? - - - AI Unconsciousness - Потеря сознания ботами - Nieprzytomność AI - Inconsciencia IA - KI-Bewusstlosigkeit - Bezvědomí AI - Inconsciência da IA - Inconscience des IA - AI eszméletlenség - Incoscienza IA - AI の気絶 - 인공지능 기절 - AI无意识 - AI無意識 - - - Allow AI to go unconscious - Позволить ботам терять сознание - Czy AI może być nieprzytomne od odniesionych obrażeń? - Permita a la IA caer inconsciente - KI kann bewusstlos werden - Umožňuje AI upadnout do bezvědomí - Permite IA ficar inconsciente - Autoriser les IA à tomber inconscients - Engedélyezi az AI eszméletének elvesztését - Permetti alle IA di diventare incoscienti - AI が気絶をするように - 인공지능도 기절에 빠지게 합니다 - 允许AI进入无意识状态 - 允許AI進入無意識狀態 - - + + States + Zustände + 状態 + Состояния + États + Estados + + + Player Fatal Injuries + Lesões Fatais do Jogador + + + Controls when players can receive fatal injuries. A fatal injury is caused by significant damage to the head or body. + Controla quando os jogadores podem receber lesões fatais. Uma lesão fatal é causada por um dano significante na cabeça ou corpo. + + + AI Fatal Injuries + Lesões Fatais da IA + + + Controls when AI can receive fatal injuries. A fatal injury is caused by significant damage to the head or body.\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 corpo.\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 Unconsciousness + Потеря сознания ботами + Nieprzytomność AI + Inconsciencia IA + KI-Bewusstlosigkeit + Bezvědomí AI + Inconsciência da IA + Inconscience des IA + AI eszméletlenség + Incoscienza IA + AI の気絶 + 인공지능 기절 + AI无意识 + AI無意識 + + + 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. + + + Cardiac Arrest Time + Zeit bis zum Herzstillstand + 心停止時間 + Длительность остановки сердца + Durée de l'arrêt cardiaque + Tempo de Parada Cardíaca + + + 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. + + + In Cardiac Arrest + Herzstillstand + 心停止中 + При остановке сердца + En arrêt cardiaque + Em Parada Cardíaca + diff --git a/addons/medical_status/ACE_settings.hpp b/addons/medical_status/ACE_settings.hpp index 11783ac42f..8613092861 100644 --- a/addons/medical_status/ACE_settings.hpp +++ b/addons/medical_status/ACE_settings.hpp @@ -5,7 +5,7 @@ class ACE_Settings { class EGVAR(medical,painCoefficient) { movedToSQF = 1; }; - class GVAR(ivFlowRate) { + class EGVAR(medical,ivFlowRate) { movedToSQF = 1; }; }; diff --git a/addons/medical_status/CfgEventHandlers.hpp b/addons/medical_status/CfgEventHandlers.hpp index 93107ab7d3..94a04d1af3 100644 --- a/addons/medical_status/CfgEventHandlers.hpp +++ b/addons/medical_status/CfgEventHandlers.hpp @@ -19,8 +19,8 @@ class Extended_PostInit_EventHandlers { class Extended_Init_EventHandlers { class CAManBase { class ADDON { - onRespawn = 1; - init = QUOTE(call FUNC(initUnit)); + init = QUOTE([ARR_2((_this select 0), false)] call FUNC(initUnit)); + exclude[] = {IGNORE_BASE_UAVPILOTS}; }; }; }; diff --git a/addons/medical_status/XEH_PREP.hpp b/addons/medical_status/XEH_PREP.hpp index 32e02d18c8..11fae9e2e6 100644 --- a/addons/medical_status/XEH_PREP.hpp +++ b/addons/medical_status/XEH_PREP.hpp @@ -4,12 +4,14 @@ PREP(getBloodLoss); PREP(getBloodPressure); PREP(getBloodVolumeChange); PREP(getCardiacOutput); +PREP(getMedicationCount); +PREP(handleKilled); PREP(hasStableVitals); PREP(initUnit); PREP(isBeingCarried); PREP(isBeingDragged); PREP(isInStableCondition); -PREP(setCardiacArrest); +PREP(setCardiacArrestState); PREP(setDead); -PREP(setUnconscious); +PREP(setUnconsciousState); PREP(updateWoundBloodLoss); diff --git a/addons/medical_status/XEH_preInit.sqf b/addons/medical_status/XEH_preInit.sqf index 9361d05015..9ef36381eb 100644 --- a/addons/medical_status/XEH_preInit.sqf +++ b/addons/medical_status/XEH_preInit.sqf @@ -8,4 +8,19 @@ PREP_RECOMPILE_END; #include "initSettings.sqf" +// Add vanilla killed EH to unit to set correct killer +["CAManBase", "init", { + params ["_unit"]; + + private _config = [_unit] call CBA_fnc_getObjectConfig; + 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)}; + + // 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)}]; + #ifdef DEBUG_MODE_FULL + if (_ehIndex != 0) then { WARNING_1("killed EH not first [%1]",_ehIndex); }; + #endif +}, nil, [IGNORE_BASE_UAVPILOTS], true] call CBA_fnc_addClassEventHandler; + ADDON = true; diff --git a/addons/medical_status/functions/fnc_adjustPainLevel.sqf b/addons/medical_status/functions/fnc_adjustPainLevel.sqf index a8fe5eebd6..c6df1adda3 100644 --- a/addons/medical_status/functions/fnc_adjustPainLevel.sqf +++ b/addons/medical_status/functions/fnc_adjustPainLevel.sqf @@ -2,6 +2,7 @@ /* * Author: PabstMirror * Interface to allow external modules to affect the pain level + * Sets the new pain level to the max between the input and current level * * Arguments: * 0: The patient diff --git a/addons/medical_status/functions/fnc_getBloodLoss.sqf b/addons/medical_status/functions/fnc_getBloodLoss.sqf index 199b92356e..ca3cba77cd 100644 --- a/addons/medical_status/functions/fnc_getBloodLoss.sqf +++ b/addons/medical_status/functions/fnc_getBloodLoss.sqf @@ -7,7 +7,7 @@ * 0: The Unit * * Return Value: - * Total blood loss of unit + * Total blood loss of unit (litres/second) * * Example: * [player] call ace_medical_status_fnc_getBloodLoss @@ -22,4 +22,5 @@ if (_woundBleeding == 0) exitWith {0}; private _cardiacOutput = [_unit] call FUNC(getCardiacOutput); -(_woundBleeding * _cardiacOutput * EGVAR(medical,bleedingCoefficient)) +// even if heart stops blood will still flow slowly (gravity) +(_woundBleeding * (_cardiacOutput max 0.05) * EGVAR(medical,bleedingCoefficient)) diff --git a/addons/medical_status/functions/fnc_getBloodPressure.sqf b/addons/medical_status/functions/fnc_getBloodPressure.sqf index 244a421201..bbb0e5b65e 100644 --- a/addons/medical_status/functions/fnc_getBloodPressure.sqf +++ b/addons/medical_status/functions/fnc_getBloodPressure.sqf @@ -17,10 +17,10 @@ */ // Value is taken because with cardic output and resistance at default values, it will put blood pressure High at 120. -#define MODIFIER_BP_HIGH 13.7142792 +#define MODIFIER_BP_HIGH 9.4736842 // Value is taken because with cardic output and resistance at default values, it will put blood pressure Low at 80. -#define MODIFIER_BP_LOW 9.1428528 +#define MODIFIER_BP_LOW 6.3157894 params ["_unit"]; diff --git a/addons/medical_status/functions/fnc_getBloodVolumeChange.sqf b/addons/medical_status/functions/fnc_getBloodVolumeChange.sqf index 904d33c79f..c46338a475 100644 --- a/addons/medical_status/functions/fnc_getBloodVolumeChange.sqf +++ b/addons/medical_status/functions/fnc_getBloodVolumeChange.sqf @@ -29,7 +29,7 @@ if (!isNil {_unit getVariable QEGVAR(medical,ivBags)}) then { _x params ["_bagVolumeRemaining", "_type", "_bodyPart"]; if (_tourniquets select _bodyPart == 0) then { - private _bagChange = (_deltaT * GVAR(ivFlowRate) * IV_CHANGE_PER_SECOND) min _bagVolumeRemaining; // absolute value of the change in miliLiters + private _bagChange = (_deltaT * EGVAR(medical,ivFlowRate) * IV_CHANGE_PER_SECOND) min _bagVolumeRemaining; // absolute value of the change in miliLiters _bagVolumeRemaining = _bagVolumeRemaining - _bagChange; _bloodVolumeChange = _bloodVolumeChange + (_bagChange / 1000); }; diff --git a/addons/medical_status/functions/fnc_getCardiacOutput.sqf b/addons/medical_status/functions/fnc_getCardiacOutput.sqf index 649fade76f..cf405b52bc 100644 --- a/addons/medical_status/functions/fnc_getCardiacOutput.sqf +++ b/addons/medical_status/functions/fnc_getCardiacOutput.sqf @@ -1,6 +1,6 @@ #include "script_component.hpp" /* - * Author: Glowbal + * Author: Glowbal, SilentSpike * Get the cardiac output from the Heart, based on current Heart Rate and Blood Volume. * * Arguments: @@ -16,17 +16,22 @@ */ /* - Cardiac output (Q or or CO ) is the volume of blood being pumped by the heart, in particular by a left or right ventricle in the CBA_missionTime interval of one second. CO may be measured in many ways, for example dm3/min (1 dm3 equals 1 litre). + Cardiac output (Q or or CO ) is the volume of blood being pumped by the heart, in particular by a left or right ventricle in the CBA_missionTime interval of one second. CO may be measured in many ways, for example dm3/min (1 dm3 equals 1 liter). Source: http://en.wikipedia.org/wiki/Cardiac_output */ -// to limit the amount of complex calculations necessary, we take a set modifier to calculate Stroke Volume. -#define MODIFIER_CARDIAC_OUTPUT 0.1904761 +// Value taken from https://doi.org/10.1093%2Feurheartj%2Fehl336 +// as 94/95 ml ± 15 ml +#define VENTRICLE_STROKE_VOL 95e-3 params ["_unit"]; -private _bloodVolumeRatio = (GET_BLOOD_VOLUME(_unit) / DEFAULT_BLOOD_VOLUME); +private _bloodVolumeRatio = GET_BLOOD_VOLUME(_unit) / DEFAULT_BLOOD_VOLUME; private _heartRate = GET_HEART_RATE(_unit); -private _cardiacOutput = ((_bloodVolumeRatio / MODIFIER_CARDIAC_OUTPUT) + ((_heartRate / DEFAULT_HEART_RATE) - 1)) / 60; -(0 max _cardiacOutput) +// Blood volume ratio dictates how much is entering the ventricle (this is an approximation) +private _entering = linearConversion [0.5, 1, _bloodVolumeRatio, 0, 1, true]; + +private _cardiacOutput = (_entering * VENTRICLE_STROKE_VOL) * _heartRate / 60; + +0 max _cardiacOutput diff --git a/addons/medical_status/functions/fnc_getMedicationCount.sqf b/addons/medical_status/functions/fnc_getMedicationCount.sqf new file mode 100644 index 0000000000..5c8b3bfd57 --- /dev/null +++ b/addons/medical_status/functions/fnc_getMedicationCount.sqf @@ -0,0 +1,39 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Gets effective count of medications in a unit's system + * (each medication dose is scaled from 0..1 based on time till max effect and max time in system) + * + * Arguments: + * 0: The patient + * 1: Medication (not case sensitive) + * 2: Get raw count (true) or effect ratio (false) (default: true) + * + * Return Value: + * Medication count (float) + * + * Example: + * [player, "Epinephrine"] call ace_medical_status_fnc_getMedicationCount + * + * Public: No + */ + +params ["_target", "_medication", ["_getCount", true]]; + +private _return = 0; +{ + _x params ["_xMed", "_timeAdded", "_timeTillMaxEffect", "_maxTimeInSystem"]; + if (_xMed == _medication) then { + private _timeInSystem = CBA_missionTime - _timeAdded; + if (_getCount) then { + // just return effective count, a medication will always start at 1 and only drop after reaching timeTilMaxEffect + _return = _return + linearConversion [_timeTillMaxEffect, _maxTimeInSystem, _timeInSystem, 1, 0, true]; + } else { + // as used in handleUnitVitals, a medication effectiveness will start low, ramp up to timeTillMaxEffect, and then drop off + _return = _return + (((_timeInSystem / _timeTillMaxEffect) ^ 2) min 1) * (_maxTimeInSystem - _timeInSystem) / _maxTimeInSystem; + }; + }; +} forEach (_target getVariable [VAR_MEDICATIONS, []]); + +TRACE_4("getMedicationCount",_target,_medication,_getCount,_return); +_return diff --git a/addons/medical_status/functions/fnc_handleKilled.sqf b/addons/medical_status/functions/fnc_handleKilled.sqf new file mode 100644 index 0000000000..25099a731d --- /dev/null +++ b/addons/medical_status/functions/fnc_handleKilled.sqf @@ -0,0 +1,41 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Vanilla Killed EH, attempts to set correct source/killer for other killed event handlers (vanilla and XEH) + * + * Arguments: + * 0: Unit + * 1: Killer + * 2: Instigator + * 3: Use Effects + * + * Return Value: + * None + * + * Example: + * [cursorObject, player, player, true] call ace_medical_status_fnc_handleKilled + * + * Public: No + */ + +params ["_unit", "_killer", "_instigator", "_useEffects"]; +TRACE_4("handleKilled",_unit,_killer,_instigator,_useEffects); + +private _causeOfDeath = _unit getVariable [QEGVAR(medical,causeOfDeath), "#scripted"]; + +// if undefined then it's a death not caused by ace's setDead (mission setDamage, disconnect) +if (_causeOfDeath != "#scripted") then { + _killer = _unit getVariable [QEGVAR(medical,lastDamageSource), _killer]; // vehicle + _instigator = _unit getVariable [QEGVAR(medical,lastInstigator), _instigator]; // unit in the turret + + // All Killed EHs uses the same array, so we can modify it now to pass the correct killer/instigator + if (missionNamespace getVariable [QEGVAR(medical,modifyKilledArray), true]) then { // getVar so this can be disabled + _this set [1, _killer]; + _this set [2, _instigator]; + }; +}; +TRACE_3("killer info",_killer,_instigator,_causeOfDeath); + +if (_unit isEqualTo (_unit getVariable [QGVAR(killed), objNull])) exitWith {}; // ensure event is only called once +_unit setVariable [QGVAR(killed), _unit]; +["ace_killed", [_unit, _causeOfDeath, _killer, _instigator]] call CBA_fnc_globalEvent; diff --git a/addons/medical_status/functions/fnc_initUnit.sqf b/addons/medical_status/functions/fnc_initUnit.sqf index d53cedbc63..4700d78393 100644 --- a/addons/medical_status/functions/fnc_initUnit.sqf +++ b/addons/medical_status/functions/fnc_initUnit.sqf @@ -5,17 +5,23 @@ * * Arguments: * 0: The Unit + * 1: Is Respawned * * Return Value: * None * * Example: - * [bob] call ace_medical_status_fnc_init + * [bob, false] call ace_medical_status_fnc_initUnit * * Public: No */ -params ["_unit"]; +params ["_unit", ["_isRespawn", true]]; +TRACE_2("initUnit",_unit,_isRespawn); + +if (!_isRespawn) then { // Always add respawn EH (same as CBA's onRespawn=1) + _unit addEventHandler ["Respawn", {[(_this select 0), true] call FUNC(initUnit)}]; +}; if (!local _unit) exitWith {}; @@ -23,58 +29,56 @@ if (damage _unit > 0) then { _unit setDamage 0; }; -// - Blood and heart ---------------------------------------------------------- -_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]; +if (_isRespawn) then { + TRACE_1("reseting all vars on respawn",_isRespawn); // note: state is handled by ace_medical_statemachine_fnc_resetStateDefault -// - Pain --------------------------------------------------------------------- -_unit setVariable [VAR_PAIN, 0, true]; -_unit setVariable [VAR_IN_PAIN, false, true]; -_unit setVariable [VAR_PAIN_SUPP, 0, true]; + // - Blood and heart ---------------------------------------------------------- + _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]; -// - Wounds ------------------------------------------------------------------- -_unit setVariable [QEGVAR(medical,openWounds), [], true]; -_unit setVariable [QEGVAR(medical,bandagedWounds), [], true]; -_unit setVariable [QEGVAR(medical,stitchedWounds), [], true]; -_unit setVariable [QEGVAR(medical,isLimping), false, true]; + // - Pain --------------------------------------------------------------------- + _unit setVariable [VAR_PAIN, 0, true]; + _unit setVariable [VAR_IN_PAIN, false, true]; + _unit setVariable [VAR_PAIN_SUPP, 0, true]; -// - Misc --------------------------------------------------------------------- -_unit setVariable [VAR_UNCON, false, true]; + // - Wounds ------------------------------------------------------------------- + _unit setVariable [VAR_OPEN_WOUNDS, [], true]; + _unit setVariable [VAR_BANDAGED_WOUNDS, [], true]; + _unit setVariable [VAR_STITCHED_WOUNDS, [], true]; + _unit setVariable [QEGVAR(medical,isLimping), false, true]; + _unit setVariable [VAR_FRACTURES, DEFAULT_FRACTURE_VALUES, true]; -// - Treatments --------------------------------------------------------------- -_unit setVariable [VAR_TOURNIQUET, DEFAULT_TOURNIQUET_VALUES, true]; -_unit setVariable [QEGVAR(medical,occludedMedications), nil, true]; //Delayed Medications (from tourniquets) -_unit setVariable [QEGVAR(medical,ivBags), nil, true]; + // - Misc --------------------------------------------------------------------- + _unit setVariable [VAR_UNCON, false, true]; -// - Update wound bleeding -[_unit] call EFUNC(medical_status,updateWoundBloodLoss); + // - Treatments --------------------------------------------------------------- + _unit setVariable [VAR_TOURNIQUET, DEFAULT_TOURNIQUET_VALUES, true]; + _unit setVariable [QEGVAR(medical,occludedMedications), nil, true]; // Delayed Medications (from tourniquets) + _unit setVariable [QEGVAR(medical,ivBags), nil, true]; -// triage card and logs -_unit setVariable [QEGVAR(medical,triageLevel), 0, true]; -_unit setVariable [QEGVAR(medical,triageCard), [], true]; + // Update wound bleeding + [_unit] call EFUNC(medical_status,updateWoundBloodLoss); -// damage storage -_unit setVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0], true]; -#ifdef DEBUG_TESTRESULTS -_unit setVariable [QEGVAR(medical,bodyPartStatus), [0,0,0,0,0,0], true]; -#endif + // Triage card and logs + _unit setVariable [QEGVAR(medical,triageLevel), 0, true]; + _unit setVariable [QEGVAR(medical,triageCard), [], true]; -// medication -_unit setVariable [VAR_MEDICATIONS, [], true]; + // Damage storage + _unit setVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0], true]; -// TODO move to treatment -private _logs = _unit getVariable [QEGVAR(medical,allLogs), []]; -{ - _unit setVariable [_x, nil]; -} forEach _logs; -_unit setVariable [QEGVAR(medical,allLogs), [], true]; + // Medication + _unit setVariable [VAR_MEDICATIONS, [], true]; + + // Unconscious spontanious wake up chance + _unit setVariable [QEGVAR(medical,lastWakeUpCheck), nil]; +}; [{ params ["_unit"]; - TRACE_2("Unit Init",_unit,local _unit); + TRACE_3("Unit Init",_unit,local _unit,typeOf _unit); [QGVAR(initialized), [_unit]] call CBA_fnc_localEvent; }, [_unit], 0.5] call CBA_fnc_waitAndExecute; diff --git a/addons/medical_status/functions/fnc_isInStableCondition.sqf b/addons/medical_status/functions/fnc_isInStableCondition.sqf index c4ee84b58e..36ff02ac2b 100644 --- a/addons/medical_status/functions/fnc_isInStableCondition.sqf +++ b/addons/medical_status/functions/fnc_isInStableCondition.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" /* * Author: Glowbal - * Check if a unit is in a stable condition + * Check if a unit is in a stable condition, needed for PersonalAidKit treatment * * Arguments: * 0: The patient @@ -17,7 +17,7 @@ params ["_unit"]; -(alive _unit - && {!IS_UNCONSCIOUS(_unit)} - && {GET_WOUND_BLEEDING(_unit) == 0} - && {_unit call FUNC(hasStableVitals)}) +alive _unit +&& {!IS_UNCONSCIOUS(_unit)} +&& {GET_WOUND_BLEEDING(_unit) == 0} +&& {_unit call FUNC(hasStableVitals)} diff --git a/addons/medical_status/functions/fnc_setCardiacArrest.sqf b/addons/medical_status/functions/fnc_setCardiacArrestState.sqf similarity index 62% rename from addons/medical_status/functions/fnc_setCardiacArrest.sqf rename to addons/medical_status/functions/fnc_setCardiacArrestState.sqf index 32c858b36d..2dd54c9c4d 100644 --- a/addons/medical_status/functions/fnc_setCardiacArrest.sqf +++ b/addons/medical_status/functions/fnc_setCardiacArrestState.sqf @@ -3,26 +3,32 @@ * Author: Glowbal * Marks a unit as in cardiac arrest and sets heart rate to 0. * Will put the unit in an unconscious state if not already. + * For Internal Use: Called from the state machine entered/leftState funcs. * * Arguments: * 0: The unit that will be put in cardiac arrest state + * 1: Set CardiacArrest * * Return Value: * None * + * Example: + * [player, true] call ace_medical_status_fnc_setCardiacArrestState + * * Public: No */ params ["_unit", "_active"]; +TRACE_2("setCardiacArrestState",_unit,_active); // No change to make -if (_active isEqualTo IN_CRDC_ARRST(_unit)) exitWith {}; +if (_active isEqualTo IN_CRDC_ARRST(_unit)) exitWith { TRACE_2("no change",_active,IN_CRDC_ARRST(_unit)); }; // No heart rate in cardiac arrest, low heart rate if revived _unit setVariable [VAR_CRDC_ARRST, _active, true]; _unit setVariable [VAR_HEART_RATE, [40, 0] select _active, true]; // Cardiac arrest is an extension of unconsciousness -[_unit, _active] call FUNC(setUnconscious); +[_unit, _active] call FUNC(setUnconsciousState); ["ace_cardiacArrest", [_unit, _active]] call CBA_fnc_localEvent; diff --git a/addons/medical_status/functions/fnc_setDead.sqf b/addons/medical_status/functions/fnc_setDead.sqf index b76ced3ddc..7f41ebf3da 100644 --- a/addons/medical_status/functions/fnc_setDead.sqf +++ b/addons/medical_status/functions/fnc_setDead.sqf @@ -13,16 +13,17 @@ * Public: No */ -params ["_unit", ["_reason", "unknown"]]; +params ["_unit", ["_reason", "#setDead"]]; +TRACE_2("setDead",_unit,_reason); // 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]; +_unit setVariable [QEGVAR(medical,causeOfDeath), _reason, true]; + +// Send a local event before death +[QEGVAR(medical,death), [_unit]] call CBA_fnc_localEvent; + // Kill the unit without changing visual apperance [_unit, 1] call EFUNC(medical_engine,setStructuralDamage); - -private _lastShooter = _unit getVariable [QEGVAR(medical,lastDamageSource), objNull]; -private _lastInstigator = _unit getVariable [QEGVAR(medical,lastInstigator), objNull]; - -["ace_killed", [_unit, _reason, _lastShooter, _lastInstigator]] call CBA_fnc_globalEvent; diff --git a/addons/medical_status/functions/fnc_setUnconscious.sqf b/addons/medical_status/functions/fnc_setUnconsciousState.sqf similarity index 60% rename from addons/medical_status/functions/fnc_setUnconscious.sqf rename to addons/medical_status/functions/fnc_setUnconsciousState.sqf index 5c3a24d759..88a37927d9 100644 --- a/addons/medical_status/functions/fnc_setUnconscious.sqf +++ b/addons/medical_status/functions/fnc_setUnconsciousState.sqf @@ -11,23 +11,32 @@ * Return Value: * Success * + * Example: + * [player, true] call ace_medical_status_fnc_setUnconsciousState + * * Public: No */ params ["_unit", "_active"]; +TRACE_2("setUnconsciousState",_unit,_active); // No change to make -if (_active isEqualTo IS_UNCONSCIOUS(_unit)) exitWith {}; +if (_active isEqualTo IS_UNCONSCIOUS(_unit)) exitWith { TRACE_2("no change",_active,IS_UNCONSCIOUS(_unit)); }; _unit setVariable [VAR_UNCON, _active, true]; // Toggle unit ragdoll state [_unit, _active] call EFUNC(medical_engine,setUnconsciousAnim); +// Stop AI firing at unconscious units in most situations (global effect) +[_unit, "setHidden", "ace_unconscious", _active] call EFUNC(common,statusEffect_set); + if (_active) then { // Don't bother setting this if not used if (EGVAR(medical,spontaneousWakeUpChance) > 0) then { - _unit setVariable [QEGVAR(medical,lastWakeUpCheck), CBA_missionTime]; + private _lastWakeUpCheck = _unit getVariable [QEGVAR(medical,lastWakeUpCheck), 0]; // could be set higher from ace_medical_fnc_setUnconscious + TRACE_2("setting lastWakeUpCheck to max of",_lastWakeUpCheck,CBA_missionTime); + _unit setVariable [QEGVAR(medical,lastWakeUpCheck), _lastWakeUpCheck max CBA_missionTime]; }; if (_unit == ACE_player) then { diff --git a/addons/medical_status/functions/fnc_updateWoundBloodLoss.sqf b/addons/medical_status/functions/fnc_updateWoundBloodLoss.sqf index 2ead65ad3a..fe38aabadc 100644 --- a/addons/medical_status/functions/fnc_updateWoundBloodLoss.sqf +++ b/addons/medical_status/functions/fnc_updateWoundBloodLoss.sqf @@ -2,6 +2,7 @@ /* * Author: Glowbal * Update total wound bleeding based on open wounds and tourniquets + * Wound bleeding = percentage of cardiac output lost * * Arguments: * 0: The Unit @@ -20,11 +21,11 @@ params ["_unit"]; private _tourniquets = GET_TOURNIQUETS(_unit); private _bodyPartBleeding = [0,0,0,0,0,0]; { - _x params ["", "", "_bodyPart", "_amountOf", "_bleeeding"]; + _x params ["", "_bodyPart", "_amountOf", "_bleeeding"]; if (_tourniquets select _bodyPart == 0) then { _bodyPartBleeding set [_bodyPart, (_bodyPartBleeding select _bodyPart) + (_amountOf * _bleeeding)]; }; -} forEach (_unit getVariable [QEGVAR(medical,openWounds), []]); +} forEach GET_OPEN_WOUNDS(_unit); if (_bodyPartBleeding isEqualTo [0,0,0,0,0,0]) then { TRACE_1("updateWoundBloodLoss-none",_unit); diff --git a/addons/medical_status/initSettings.sqf b/addons/medical_status/initSettings.sqf index 1118973f37..95231b0acc 100644 --- a/addons/medical_status/initSettings.sqf +++ b/addons/medical_status/initSettings.sqf @@ -1,33 +1,26 @@ -// CBA Settings [ADDON: ace_medical_status]: - -private _categoryArray = [LELSTRING(medical,Category_DisplayName), LLSTRING(subCategory)]; - [ - QEGVAR(medical,bleedingCoefficient), "SLIDER", - [LSTRING(bleedingCoefficient_DisplayName), LSTRING(bleedingCoefficient_Description)], - _categoryArray, - [0,25,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QEGVAR(medical,bleedingCoefficient), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QEGVAR(medical,bleedingCoefficient), + "SLIDER", + [LSTRING(BleedingCoefficient_DisplayName), LSTRING(BleedingCoefficient_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], + [0, 25, 1, 1], + true ] call CBA_settings_fnc_init; [ - QEGVAR(medical,painCoefficient), "SLIDER", - [LSTRING(painCoefficient_DisplayName), LSTRING(painCoefficient_Description)], - _categoryArray, - [0,25,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QEGVAR(medical,painCoefficient), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QEGVAR(medical,painCoefficient), + "SLIDER", + [LSTRING(PainCoefficient_DisplayName), LSTRING(PainCoefficient_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], + [0, 25, 1, 1], + true ] call CBA_settings_fnc_init; [ - QGVAR(ivFlowRate), "SLIDER", - [LSTRING(ivFlowRate_DisplayName), LSTRING(ivFlowRate_Description)], - _categoryArray, - [0,25,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(ivFlowRate), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QEGVAR(medical,ivFlowRate), + "SLIDER", + [LSTRING(IvFlowRate_DisplayName), LSTRING(IvFlowRate_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], + [0, 25, 1, 1], + true ] call CBA_settings_fnc_init; diff --git a/addons/medical_status/stringtable.xml b/addons/medical_status/stringtable.xml index a92a16c7b6..86f79b2784 100644 --- a/addons/medical_status/stringtable.xml +++ b/addons/medical_status/stringtable.xml @@ -1,80 +1,93 @@ - - - Status - - - Bleeding coefficient - Коэффициент кровопотери - Mnożnik krwawienia - Coeficiente de sangrado - Verblutungsmultiplikator - Koeficient krvácení - Coeficiente de sangramento - Coéfficient de saignement - Vérzési koefficiens - Coefficiente sanguinamento - 出血の係数 - 출혈 계수 - 流血系数 - 流血係數 - - - Coefficient to modify the bleeding speed - Коэффициент, изменяющий скорость потери крови - Mnożnik modyfikujący prędkość wykrwawiania się - Coeficiente para modificar la velocidad de sangrado - Multiplikator um die Verblutungsgeschwindigkeit zu verändern - Koeficient rychlosti krvácení - Coeficiente para modificar a velocidade do sangramento - Modifie le débit des saignements - Egy szorzó a vérzés sebességének szabályozására - Coefficiente che modifica la velocità di sanguinamento - この係数では出血速度を変更できます - 출혈의 속도를 계수만큼 변경합니다 - 修改流血速度 - 修改流血速度 - - - Pain coefficient - Коэффициент боли - Mnożnik bólu - Coeficiente de dolor - Schmerzmultiplikator - Koeficient bolesti - Coeficiente de dor - Coéfficient de douleur - Fájdalmi koefficiens - Coefficiente dolore - 痛みの係数 - 고통 계수 - 疼痛系数 - 疼痛係數 - - - Coefficient to modify the pain intensity - Коэффициент, изменяющий уровень боли - Mnożnik modyfikujący intensywność bólu - Coeficiente para modificar la intensidad del dolor - Multiplikator um die Schmerzintensität zu verändern - Koeficient intenzity bolesti - Coeficiente para modificar a instensidade de dor - Modifie l'intensité de la douleur - Egy szorzó a fájdalom erősségének szabályozására - Coefficiente che modifica l'intensità del dolore - この係数では痛みの強さを変更できます - 고통의 정도를 계수만큼 변경합니다 - 修改疼痛强度的系数 - 修改疼痛強度的係數 - - - IV Transfusion Flow Rate - - - Effects how quickly IV Bags will have effect - - + + Status + Zustand + 状態 + Статус + Statut + Status + + + Bleeding Coefficient + Коэффициент кровопотери + Mnożnik krwawienia + Coeficiente de sangrado + Verblutungsmultiplikator + Koeficient krvácení + Coeficiente de sangramento + Coefficient de saignement + Vérzési koefficiens + Coefficiente sanguinamento + 出血の係数 + 출혈 계수 + 流血系数 + 流血係數 + + + Coefficient for controlling the bleeding speed. + Коэффициент, изменяющий скорость потери крови + Mnożnik modyfikujący prędkość wykrwawiania się + Coeficiente para modificar la velocidad de sangrado + Multiplikator um die Verblutungsgeschwindigkeit zu verändern + Koeficient rychlosti krvácení + Coeficiente para modificar a velocidade do sangramento + Coefficient permettant de définir la vitesse du saignement. + Egy szorzó a vérzés sebességének szabályozására + Coefficiente che modifica la velocità di sanguinamento + この係数では出血速度を変更できます + 출혈의 속도를 계수만큼 변경합니다 + 修改流血速度 + 修改流血速度 + + + Pain Coefficient + Коэффициент боли + Mnożnik bólu + Coeficiente de dolor + Schmerzmultiplikator + Koeficient bolesti + Coeficiente de dor + Coefficient de douleur + Fájdalmi koefficiens + Coefficiente dolore + 痛みの係数 + 고통 계수 + 疼痛系数 + 疼痛係數 + + + Coefficient for controlling the intensity of pain adjustments. + Коэффициент, изменяющий уровень боли + Mnożnik modyfikujący intensywność bólu + Coeficiente para modificar la intensidad del dolor + Multiplikator um die Schmerzintensität zu verändern + Koeficient intenzity bolesti + Coeficiente para modificar a instensidade de dor + Coefficient permettant de définir l'intensité de la douleur. + Egy szorzó a fájdalom erősségének szabályozására + Coefficiente che modifica l'intensità del dolore + この係数では痛みの強さを変更できます + 고통의 정도를 계수만큼 변경합니다 + 修改疼痛强度的系数 + 修改疼痛強度的係數 + + + IV Transfusion Flow Rate + Transfusions Fließrate + IV 輸血の流量 + Скорость внутривенного переливания + Débit de transfusion IV + Velocidade de Transferência de Sangue + + + 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 による輸血速度を変更できます + Определяет, насколько быстро подействуют эффекты внутривенного переливания + 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 flúidos 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) + diff --git a/addons/medical_treatment/ACE_Medical_Facilities.hpp b/addons/medical_treatment/ACE_Medical_Facilities.hpp new file mode 100644 index 0000000000..32ab19d233 --- /dev/null +++ b/addons/medical_treatment/ACE_Medical_Facilities.hpp @@ -0,0 +1,26 @@ +class EGVAR(medical,facilities) { + BI[] = { + "Land_Medevac_house_V1_F", + "Land_Medevac_HQ_V1_F", + "Land_MedicalTent_01_white_IDAP_med_closed_F", + "Land_MedicalTent_01_MTP_closed_F", + "Land_MedicalTent_01_brownhex_closed_F", + "Land_MedicalTent_01_digital_closed_F" + }; + CUP[] = { + "TK_GUE_WarfareBFieldhHospital_Base_EP1", + "TK_GUE_WarfareBFieldhHospital_EP1", + "TK_WarfareBFieldhHospital_Base_EP1", + "TK_WarfareBFieldhHospital_EP1", + "US_WarfareBFieldhHospital_Base_EP1", + "US_WarfareBFieldhHospital_EP1", + "MASH_EP1", + "MASH", + "Land_A_Hospital", + "CDF_WarfareBFieldhHospital", + "GUE_WarfareBFieldhHospital", + "INS_WarfareBFieldhHospital", + "RU_WarfareBFieldhHospital", + "USMC_WarfareBFieldhHospital" + }; +}; diff --git a/addons/medical_treatment/ACE_Medical_Treatment.hpp b/addons/medical_treatment/ACE_Medical_Treatment.hpp index 88a2e46663..1c357ec564 100644 --- a/addons/medical_treatment/ACE_Medical_Treatment.hpp +++ b/addons/medical_treatment/ACE_Medical_Treatment.hpp @@ -297,7 +297,7 @@ class ADDON { reopeningMaxDelay = 150; }; class AbrasionMinor: Abrasion { - effectiveness = 43; + effectiveness = 4; }; class AbrasionMedium: Abrasion { effectiveness = 3; @@ -582,7 +582,7 @@ class ADDON { timeInSystem = 1800; timeTillMaxEffect = 30; maxDose = 4; - inCompatableMedication[] = {}; + incompatibleMedication[] = {}; viscosityChange = -10; }; class Epinephrine { @@ -593,7 +593,7 @@ class ADDON { timeInSystem = 120; timeTillMaxEffect = 10; maxDose = 10; - inCompatableMedication[] = {}; + incompatibleMedication[] = {}; }; class Adenosine { painReduce = 0; @@ -603,24 +603,14 @@ class ADDON { timeInSystem = 120; timeTillMaxEffect = 15; maxDose = 6; - inCompatableMedication[] = {}; - }; - class Atropine { - painReduce = 0; - hrIncreaseLow[] = {-2, -5}; - hrIncreaseNormal[] = {-10, -15}; - hrIncreaseHigh[] = {-5, -20}; - timeInSystem = 120; - timeTillMaxEffect = 15; - maxDose = 6; - inCompatableMedication[] = {}; + incompatibleMedication[] = {}; }; class PainKillers { painReduce = 0.1; timeInSystem = 600; timeTillMaxEffect = 60; maxDose = 10; - inCompatableMedication[] = {}; + incompatibleMedication[] = {}; viscosityChange = 5; }; }; diff --git a/addons/medical_treatment/ACE_Medical_Treatment_Actions.hpp b/addons/medical_treatment/ACE_Medical_Treatment_Actions.hpp index ae1582c040..74f02397c6 100644 --- a/addons/medical_treatment/ACE_Medical_Treatment_Actions.hpp +++ b/addons/medical_treatment/ACE_Medical_Treatment_Actions.hpp @@ -1,39 +1,46 @@ - -class GVAR(Actions) { - // --- bandages +class GVAR(actions) { + // - Bandages ------------------------------------------------------------- class BasicBandage { displayName = CSTRING(Bandage); displayNameProgress = CSTRING(Bandaging); icon = QPATHTOEF(medical_gui,ui\bandage.paa); category = "bandage"; - treatmentLocations[] = {"All"}; - allowedSelections[] = {"All"}; - allowSelfTreatment = 1; - requiredMedic = 0; - treatmentTime = QFUNC(getBandageTime); - treatmentTimeSelfCoef = 1; - items[] = {{"ACE_fieldDressing", "ACE_packingBandage", "ACE_elasticBandage", "ACE_quikclot"}}; - condition = QFUNC(canBandage); - itemConsumed = 1; - callbackSuccess = QFUNC(treatmentBandage); - callbackFailure = ""; - callbackProgress = ""; - animationCaller = "AinvPknlMstpSlayW[wpn]Dnon_medicOther"; - animationCallerProne = "AinvPpneMstpSlayW[wpn]Dnon_medicOther"; - animationCallerSelf = "AinvPknlMstpSlayW[wpn]Dnon_medic"; - animationCallerSelfProne = "AinvPpneMstpSlayW[wpn]Dnon_medic"; + consumeItem = 1; + items[] = {"ACE_fieldDressing", "ACE_packingBandage", "ACE_elasticBandage", "ACE_quikclot"}; + + medicRequired = 0; + allowSelfTreatment = 1; + allowedSelections[] = {"All"}; + condition = QFUNC(canBandage); + treatmentLocations = TREATMENT_LOCATIONS_ALL; + + treatmentTime = QFUNC(getBandageTime); + treatmentTimeSelfCoef = 1; // todo: this isn't used anywhere, remove? + + callbackStart = ""; + callbackProgress = ""; + callbackSuccess = QFUNC(bandage); + callbackFailure = ""; + + animationMedic = "AinvPknlMstpSlayW[wpn]Dnon_medicOther"; + animationMedicProne = "AinvPpneMstpSlayW[wpn]Dnon_medicOther"; + animationMedicSelf = "AinvPknlMstpSlayW[wpn]Dnon_medic"; + animationMedicSelfProne = "AinvPpneMstpSlayW[wpn]Dnon_medic"; + litter[] = { - {"All", "_bloodLossOnBodyPart > 0", {{"ACE_MedicalLitterBase", "ACE_MedicalLitter_bandage1", "ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}}}, - {"All", "_bloodLossOnBodyPart <= 0", {"ACE_MedicalLitter_clean"}} + {}, + {"ACE_MedicalLitter_clean"}, + {{"ACE_MedicalLitterBase", "ACE_MedicalLitter_bandage1", "ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}} }; }; class FieldDressing: BasicBandage { displayName = CSTRING(Actions_FieldDressing); items[] = {"ACE_fieldDressing"}; litter[] = { - {"All", "_bloodLossOnBodyPart > 0", {{"ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}}}, - {"All", "_bloodLossOnBodyPart <= 0", {"ACE_MedicalLitter_clean"}} + {}, + {"ACE_MedicalLitter_clean"}, + {{"ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}} }; }; class PackingBandage: BasicBandage { @@ -41,50 +48,67 @@ class GVAR(Actions) { icon = QPATHTOEF(medical_gui,ui\packing_bandage.paa); items[] = {"ACE_packingBandage"}; litter[] = { - {"All", "", {"ACE_MedicalLitter_packingBandage"}}, - {"All", "_bloodLossOnBodyPart > 0", {{"ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}}}, - {"All", "_bloodLossOnBodyPart <= 0", {"ACE_MedicalLitter_clean"}} + {"ACE_MedicalLitter_packingBandage"}, + {"ACE_MedicalLitter_clean"}, + {{"ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}} }; }; class ElasticBandage: BasicBandage { displayName = CSTRING(Actions_ElasticBandage); items[] = {"ACE_elasticBandage"}; litter[] = { - {"All", "_bloodLossOnBodyPart > 0", {{"ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}}}, - {"All", "_bloodLossOnBodyPart <= 0", {"ACE_MedicalLitter_clean"}} + {}, + {"ACE_MedicalLitter_clean"}, + {{"ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}} }; }; class QuikClot: BasicBandage { displayName = CSTRING(Actions_QuikClot); items[] = {"ACE_quikclot"}; litter[] = { - {"All", "", {"ACE_MedicalLitter_QuickClot"}}, - {"All", "_bloodLossOnBodyPart > 0", {{"ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}}}, - {"All", "_bloodLossOnBodyPart <= 0", {"ACE_MedicalLitter_clean"}} + {"ACE_MedicalLitter_QuickClot"}, + {"ACE_MedicalLitter_clean"}, + {{"ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}} }; }; - // --- tourniquet - class Tourniquet: BasicBandage { + // - Tourniquets ---------------------------------------------------------- + class ApplyTourniquet: BasicBandage { displayName = CSTRING(Apply_Tourniquet); displayNameProgress = CSTRING(Applying_Tourniquet); icon = QPATHTOEF(medical_gui,ui\tourniquet.paa); allowedSelections[] = {"LeftArm", "RightArm", "LeftLeg", "RightLeg"}; items[] = {"ACE_tourniquet"}; treatmentTime = 7; - callbackSuccess = QFUNC(treatmentTourniquet); - condition = QUOTE(!([ARR_2(_target,_bodyPart)] call FUNC(hasTourniquetAppliedTo))); + condition = QUOTE(!([ARR_2(_patient,_bodyPart)] call FUNC(hasTourniquetAppliedTo))); + callbackSuccess = QFUNC(tourniquet); litter[] = {}; }; - class RemoveTourniquet: Tourniquet { + class RemoveTourniquet: ApplyTourniquet { displayName = CSTRING(Actions_RemoveTourniquet); displayNameProgress = CSTRING(RemovingTourniquet); items[] = {}; - callbackSuccess = QFUNC(treatmentTourniquetRemove); - condition = QUOTE([ARR_2(_target,_bodyPart)] call FUNC(hasTourniquetAppliedTo)); + condition = QUOTE([ARR_2(_patient,_bodyPart)] call FUNC(hasTourniquetAppliedTo)); + callbackSuccess = QFUNC(tourniquetRemove); }; - // --- syringes + // - Splint --------------------------------------------------------------- + class Splint: BasicBandage { + displayName = CSTRING(Apply_Splint); + displayNameProgress = CSTRING(Applying_Splint); + category = "bandage"; + icon = QPATHTOEF(medical_gui,ui\splint.paa); + allowedSelections[] = {"LeftArm", "RightArm", "LeftLeg", "RightLeg"}; + items[] = {"ACE_splint"}; + treatmentTime = 7; + callbackSuccess = QFUNC(splint); + condition = QFUNC(canSplint); + litter[] = { + {"ACE_MedicalLitter_splint"}, {}, {} + }; + }; + + // - Syringes ------------------------------------------------------------- class Morphine: FieldDressing { displayName = CSTRING(Inject_Morphine); displayNameProgress = CSTRING(Injecting_Morphine); @@ -94,35 +118,28 @@ class GVAR(Actions) { items[] = {"ACE_morphine"}; condition = ""; treatmentTime = 5; - callbackSuccess = QFUNC(treatmentMedication); - animationCaller = "AinvPknlMstpSnonWnonDnon_medic1"; - litter[] = { {"All", "", {"ACE_MedicalLitter_morphine"}} }; + callbackSuccess = QFUNC(medication); + animationMedic = "AinvPknlMstpSnonWnonDnon_medic1"; sounds[] = {{QPATHTO_R(sounds\Inject.ogg),1,1,50}}; + litter[] = {{"ACE_MedicalLitter_morphine"}}; }; class Adenosine: Morphine { displayName = CSTRING(Inject_Adenosine); displayNameProgress = CSTRING(Injecting_Adenosine); condition = QGVAR(advancedMedication); items[] = {"ACE_adenosine"}; - litter[] = { {"All", "", {"ACE_MedicalLitter_adenosine"}} }; - }; - class Atropine: Morphine { - displayName = CSTRING(Inject_Atropine); - displayNameProgress = CSTRING(Injecting_Atropine); - condition = QGVAR(advancedMedication); - items[] = {"ACE_atropine"}; - litter[] = { {"All", "", {"ACE_MedicalLitter_atropine"}} }; + litter[] = {{"ACE_MedicalLitter_adenosine"}}; }; class Epinephrine: Morphine { displayName = CSTRING(Inject_Epinephrine); displayNameProgress = CSTRING(Injecting_Epinephrine); - requiredMedic = QEGVAR(medical,medicSetting_Epi); + medicRequired = QGVAR(medicEpinephrine); items[] = {"ACE_epinephrine"}; - litter[] = { {"All", "", {"ACE_MedicalLitter_epinephrine"}} }; - treatmentLocations[] = {QEGVAR(medical,useLocation_Epi)}; + treatmentLocations = QGVAR(locationEpinephrine); + litter[] = {{"ACE_MedicalLitter_epinephrine"}}; }; - // --- iv bags + // - IV Bags -------------------------------------------------------------- class BloodIV: BasicBandage { displayName = CSTRING(Actions_Blood4_1000); displayNameProgress = CSTRING(Transfusing_Blood); @@ -130,12 +147,12 @@ class GVAR(Actions) { allowedSelections[] = {"LeftArm", "RightArm", "LeftLeg", "RightLeg"}; allowSelfTreatment = QGVAR(allowSelfIV); category = "advanced"; - requiredMedic = 1; + medicRequired = 1; treatmentTime = 12; items[] = {"ACE_bloodIV"}; condition = ""; - callbackSuccess = QFUNC(treatmentIV); - animationCaller = "AinvPknlMstpSnonWnonDnon_medic1"; + callbackSuccess = QFUNC(ivBag); + animationMedic = "AinvPknlMstpSnonWnonDnon_medic1"; litter[] = {}; }; class BloodIV_500: BloodIV { @@ -150,7 +167,7 @@ class GVAR(Actions) { displayName = CSTRING(Actions_Plasma4_1000); displayNameProgress = CSTRING(Transfusing_Plasma); items[] = {"ACE_plasmaIV"}; - animationCaller = "AinvPknlMstpSnonWnonDnon_medic1"; + animationMedic = "AinvPknlMstpSnonWnonDnon_medic1"; }; class PlasmaIV_500: PlasmaIV { displayName = CSTRING(Actions_Plasma4_500); @@ -164,7 +181,7 @@ class GVAR(Actions) { displayName = CSTRING(Actions_Saline4_1000); displayNameProgress = CSTRING(Transfusing_Saline); items[] = {"ACE_salineIV"}; - animationCaller = "AinvPknlMstpSnonWnonDnon_medic1"; + animationMedic = "AinvPknlMstpSnonWnonDnon_medic1"; }; class SalineIV_500: SalineIV { displayName = CSTRING(Actions_Saline4_500); @@ -175,23 +192,23 @@ class GVAR(Actions) { items[] = {"ACE_salineIV_250"}; }; - // --- diagnose + // - Diagnose ------------------------------------------------------------- class Diagnose: BasicBandage { displayName = CSTRING(Actions_Diagnose); displayNameProgress = CSTRING(Actions_Diagnosing); icon = ""; category = "examine"; - treatmentLocations[] = {"All"}; + treatmentLocations = TREATMENT_LOCATIONS_ALL; allowedSelections[] = {"Head", "Body"}; - requiredMedic = 0; + medicRequired = 0; treatmentTime = 2.5; items[] = {}; condition = QUOTE(!GVAR(advancedDiagnose)); - callbackSuccess = QFUNC(actionDiagnose); + callbackSuccess = QFUNC(diagnose); callbackFailure = ""; callbackProgress = ""; - animationCaller = ""; // TODO - itemConsumed = 0; + animationMedic = ""; // TODO + consumeItem = 0; litter[] = {}; }; class CheckPulse: Diagnose { @@ -199,40 +216,38 @@ class GVAR(Actions) { displayNameProgress = CSTRING(Check_Pulse_Content); allowedSelections[] = {"All"}; condition = QGVAR(advancedDiagnose); - callbackSuccess = QFUNC(actionCheckPulse); - animationCallerProne = ""; - animationCallerSelfProne = ""; + callbackSuccess = QFUNC(checkPulse); + animationMedicProne = ""; + animationMedicSelfProne = ""; }; class CheckBloodPressure: CheckPulse { displayName = CSTRING(Actions_CheckBloodPressure); displayNameProgress = CSTRING(Check_Bloodpressure_Content); allowedSelections[] = {"LeftArm", "RightArm", "LeftLeg", "RightLeg"}; - callbackSuccess = QFUNC(actionCheckBloodPressure); + callbackSuccess = QFUNC(checkBloodPressure); }; class CheckResponse: CheckPulse { displayName = CSTRING(Check_Response); displayNameProgress = CSTRING(Check_Response_Content); allowedSelections[] = {"Head"}; allowSelfTreatment = 0; - callbackSuccess = QFUNC(actionCheckResponse); + callbackSuccess = QFUNC(checkResponse); }; - // --- misc + // - Misc ----------------------------------------------------------------- class BodyBag: BasicBandage { displayName = CSTRING(PlaceInBodyBag); displayNameProgress = CSTRING(PlacingInBodyBag); icon = QPATHTOEF(medical_gui,ui\bodybag.paa); category = "advanced"; - treatmentLocations[] = {"All"}; + treatmentLocations = TREATMENT_LOCATIONS_ALL; allowSelfTreatment = 0; - requiredMedic = 0; + medicRequired = 0; treatmentTime = 15; items[] = {"ACE_bodyBag"}; - condition = "!alive _target"; - callbackSuccess = QFUNC(actionPlaceInBodyBag); - callbackFailure = ""; - callbackProgress = ""; - itemConsumed = 1; + condition = QUOTE(!alive _patient); + callbackSuccess = QFUNC(placeInBodyBag); + consumeItem = 1; litter[] = {}; }; class CPR: BasicBandage { @@ -240,62 +255,64 @@ class GVAR(Actions) { displayNameProgress = CSTRING(Actions_PerformingCPR); icon = ""; category = "advanced"; - treatmentLocations[] = {"All"}; + treatmentLocations = TREATMENT_LOCATIONS_ALL; allowedSelections[] = {"Body"}; allowSelfTreatment = 0; - requiredMedic = 0; + medicRequired = 0; treatmentTime = 15; items[] = {}; - condition = QUOTE(!(_target call EFUNC(common,isAwake)) && {!(_target getVariable [ARR_2('GVAR(receiveCPR)', false)])}); - callbackSuccess = QFUNC(treatmentCPR); - callbackFailure = QFUNC(treatmentCPR_failure); - callbackProgress = QFUNC(treatmentCPR_progress); - callbackStart = QFUNC(treatmentCPR_start); - animationCaller = "AinvPknlMstpSlayW[wpn]Dnon_medic"; - animationCallerProne = "AinvPpneMstpSlayW[wpn]Dnon_medic"; - animationCallerSelf = ""; - animationCallerSelfProne = ""; - itemConsumed = 0; + condition = QFUNC(canCPR); + callbackSuccess = QFUNC(cprSuccess); + callbackFailure = QFUNC(cprFailure); + callbackProgress = QFUNC(cprProgress); + callbackStart = QFUNC(cprStart); + animationMedic = "AinvPknlMstpSnonWnonDr_medic0"; + animationMedicProne = "AinvPknlMstpSnonWnonDr_medic0"; + animationMedicSelf = ""; + animationMedicSelfProne = ""; + consumeItem = 0; litter[] = {}; }; - class SurgicalKit: FieldDressing { displayName = CSTRING(Use_SurgicalKit); displayNameProgress = CSTRING(Stitching); icon = QPATHTOEF(medical_gui,ui\surgical_kit.paa); category = "advanced"; items[] = {"ACE_surgicalKit"}; - treatmentLocations[] = {QEGVAR(medical,useLocation_SurgicalKit)}; - allowSelfTreatment = 0; - requiredMedic = QEGVAR(medical,medicSetting_SurgicalKit); - treatmentTime = QUOTE(count (_target getVariable [ARR_2('EGVAR(medical,bandagedWounds)',[])]) * 5); + treatmentLocations = QGVAR(locationSurgicalKit); + allowSelfTreatment = QGVAR(allowSelfStitch); + medicRequired = QGVAR(medicSurgicalKit); + treatmentTime = QFUNC(getStitchTime); condition = QFUNC(canStitch); callbackSuccess = ""; - callbackProgress = QFUNC(treatmentSurgicalKit_onProgress); - itemConsumed = QEGVAR(medical,consumeItem_SurgicalKit); - animationCaller = "AinvPknlMstpSnonWnonDnon_medic1"; - litter[] = { {"All", "", {"ACE_MedicalLitter_gloves"} }}; + callbackProgress = QFUNC(surgicalKitProgress); + consumeItem = QGVAR(consumeSurgicalKit); + animationMedic = "AinvPknlMstpSnonWnonDnon_medic1"; + litter[] = {{"ACE_MedicalLitter_gloves"}}; }; class PersonalAidKit: BasicBandage { displayName = CSTRING(Use_Aid_Kit); displayNameProgress = CSTRING(TreatmentAction); icon = ""; category = "advanced"; - condition = QUOTE(_target call EFUNC(medical_status,isInStableCondition)); + condition = QUOTE(_patient call EFUNC(medical_status,isInStableCondition)); items[] = {"ACE_personalAidKit"}; - treatmentLocations[] = {QEGVAR(medical,useLocation_PAK)}; - requiredMedic = QEGVAR(medical,medicSetting_PAK); - treatmentTime = QUOTE(_target call FUNC(healTime)); - callbackSuccess = QFUNC(treatmentFullHeal); - itemConsumed = QEGVAR(medical,consumeItem_PAK); - animationCaller = "AinvPknlMstpSlayW[wpn]Dnon_medicOther"; - animationCallerProne = "AinvPpneMstpSlayW[wpn]Dnon_medicOther"; - animationCallerSelf = ""; - animationCallerSelfProne = ""; - litter[] = { {"All", "", {"ACE_MedicalLitter_gloves"}}, - {"All", "_bloodLossOnBodyPart > 0", {{"ACE_MedicalLitterBase", "ACE_MedicalLitter_bandage1", "ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}}}, - {"All", "_bloodLossOnBodyPart > 0", {{"ACE_MedicalLitterBase", "ACE_MedicalLitter_bandage1", "ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}}}, - {"All", "_bloodLossOnBodyPart <= 0", {"ACE_MedicalLitter_clean"}} + treatmentLocations = QGVAR(locationPAK); + medicRequired = QGVAR(medicPAK); + treatmentTime = QFUNC(getHealTime); + callbackSuccess = QFUNC(fullHeal); + consumeItem = QGVAR(consumePAK); + animationMedic = "AinvPknlMstpSlayW[wpn]Dnon_medicOther"; + animationMedicProne = "AinvPpneMstpSlayW[wpn]Dnon_medicOther"; + animationMedicSelf = ""; + animationMedicSelfProne = ""; + litter[] = { + {"ACE_MedicalLitter_gloves"}, + {"ACE_MedicalLitter_clean"}, + { + {"ACE_MedicalLitterBase", "ACE_MedicalLitter_bandage1", "ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}, + {"ACE_MedicalLitterBase", "ACE_MedicalLitter_bandage1", "ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"} + } }; }; }; diff --git a/addons/medical_treatment/ACE_Settings.hpp b/addons/medical_treatment/ACE_Settings.hpp deleted file mode 100644 index 309c923299..0000000000 --- a/addons/medical_treatment/ACE_Settings.hpp +++ /dev/null @@ -1,48 +0,0 @@ -class ACE_Settings { - class EGVAR(medical,allowLitterCreation) { - movedToSqf = 1; - }; - class EGVAR(medical,CPRcreatesPulse) { - movedToSqf = 1; - }; - class EGVAR(medical,litterCleanUpDelay) { - movedToSqf = 1; - }; - class EGVAR(medical,litterSimulationDetail) { - movedToSqf = 1; - _values[] = { 0, 50, 100, 1000, 5000 }; - }; - class EGVAR(medical,increaseTrainingInLocations) { - movedToSqf = 1; - }; - class EGVAR(medical,PAKTime) { - movedToSqf = 1; - }; - class EGVAR(medical,medicSetting_Epi) { - movedToSqf = 1; - }; - class EGVAR(medical,medicSetting_PAK) { - movedToSqf = 1; - }; - class EGVAR(medical,medicSetting_SurgicalKit) { - movedToSqf = 1; - }; - class EGVAR(medical,consumeItem_PAK) { - movedToSqf = 1; - }; - class EGVAR(medical,consumeItem_SurgicalKit) { - movedToSqf = 1; - }; - class EGVAR(medical,useLocation_Epi) { - movedToSqf = 1; - }; - class EGVAR(medical,useLocation_PAK) { - movedToSqf = 1; - }; - class EGVAR(medical,useLocation_SurgicalKit) { - movedToSqf = 1; - }; - class EGVAR(medical,convertItems) { - movedToSqf = 1; - }; -}; diff --git a/addons/medical_treatment/CfgEden.hpp b/addons/medical_treatment/Cfg3DEN.hpp similarity index 57% rename from addons/medical_treatment/CfgEden.hpp rename to addons/medical_treatment/Cfg3DEN.hpp index d3c2f6c721..04c3fc3efd 100644 --- a/addons/medical_treatment/CfgEden.hpp +++ b/addons/medical_treatment/Cfg3DEN.hpp @@ -1,3 +1,11 @@ + +#define GRID_3DEN_W (pixelW * pixelGrid * 0.5) +#define GRID_3DEN_H (pixelH * pixelGrid * 0.5) + +#define DEFAULT_IS_MEDIC (parseNumber (_this getUnitTrait 'medic')) +#define DEFAULT_IS_MEDICAL_VEHICLE (getNumber (configFile >> 'CfgVehicles' >> typeOf _this >> 'attendant') > 0) +#define DEFAULT_IS_MEDICAL_FACILITY (typeOf _this in GVAR(facilityClasses)) + class ctrlToolbox; class Cfg3DEN { @@ -9,19 +17,23 @@ class Cfg3DEN { }; }; class GVAR(isMedicControl): Title { - attributeLoad = "(_this controlsGroupCtrl 100) lbSetCurSel (((_value + 1) min 3) max 0);"; - attributeSave = "(lbCurSel (_this controlsGroupCtrl 100)) - 1"; + attributeLoad = QUOTE((_this controlsGroupCtrl 100) lbSetCurSel (0 max (_value + 1) min 3)); + attributeSave = QUOTE(lbCurSel (_this controlsGroupCtrl 100) - 1); class Controls: Controls { - class Title: Title{}; + class Title: Title {}; class Value: ctrlToolbox { idc = 100; - style = "0x02"; - x = "48 * (pixelW * pixelGrid * 0.50)"; - w = "82 * (pixelW * pixelGrid * 0.50)"; - h = "5 * (pixelH * pixelGrid * 0.50)"; + x = 48 * GRID_3DEN_W; + w = 82 * GRID_3DEN_W; + h = 5 * GRID_3DEN_H; rows = 1; columns = 4; - strings[] = {"$STR_3DEN_Attributes_Lock_Default_text", CSTRING(AssignMedicRoles_role_none), CSTRING(AssignMedicRoles_role_medic), CSTRING(AssignMedicRoles_role_doctorShort)}; + strings[] = { + "$STR_3DEN_Attributes_Lock_Default_text", + CSTRING(AssignMedicRoles_role_none), + CSTRING(AssignMedicRoles_role_medic), + CSTRING(AssignMedicRoles_role_doctorShort) + }; }; }; }; @@ -31,36 +43,34 @@ class Cfg3DEN { class ace_attributes { class Attributes { class ace_isMedic { - property = QUOTE(ace_isMedic); - control = QGVAR(isMedicControl); displayName = CSTRING(AssignMedicRoles_role_DisplayName); tooltip = CSTRING(Attributes_isMedic_Description); - expression = QUOTE(if (_value > -1) then {_this setVariable [ARR_3(QQEGVAR(medical,medicClass),_value,true)];};); - typeName = "NUMBER"; + property = QUOTE(ace_isMedic); + control = QGVAR(isMedicControl); + expression = QUOTE(if (_value != -1 && {_value != DEFAULT_IS_MEDIC}) then {_this setVariable [ARR_3(QQEGVAR(medical,medicClass),_value,true)]}); + defaultValue = QUOTE(DEFAULT_IS_MEDIC); condition = "objectBrain"; - defaultValue = "-1"; + typeName = "NUMBER"; }; class ace_isMedicalVehicle { - property = QUOTE(ace_isMedicalVehicle); - value = 0; - control = "CheckboxNumber"; displayName = CSTRING(AssignMedicVehicle_enabled_DisplayName); tooltip = CSTRING(Attributes_isMedicalVehicle_Description); - expression = QUOTE(_this setVariable [ARR_3(QQEGVAR(medical,medicClass),_value,true)];); - typeName = "NUMBER"; + property = QUOTE(ace_isMedicalVehicle); + control = "Checkbox"; + expression = QUOTE(_this setVariable [ARR_3(QQEGVAR(medical,isMedicalVehicle),_value,true)]); + defaultValue = QUOTE(DEFAULT_IS_MEDICAL_VEHICLE); condition = "objectVehicle"; - defaultValue = 0; + typeName = "BOOL"; }; class ace_isMedicalFacility { - property = QUOTE(ace_isMedicalFacility); - value = 0; - control = "Checkbox"; displayName = CSTRING(AssignMedicalFacility_enabled_DisplayName); tooltip = CSTRING(AssignMedicalFacility_enabled_Description); + property = QUOTE(ace_isMedicalFacility); + control = "Checkbox"; expression = QUOTE(_this setVariable [ARR_3(QQEGVAR(medical,isMedicalFacility),_value,true)];); - typeName = "BOOL"; + defaultValue = QUOTE(DEFAULT_IS_MEDICAL_FACILITY); condition = "(1 - objectBrain) * (1 - objectVehicle)"; - defaultValue = "false"; + typeName = "BOOL"; }; }; }; diff --git a/addons/medical_treatment/CfgReplacementItems.hpp b/addons/medical_treatment/CfgReplacementItems.hpp new file mode 100644 index 0000000000..16a45d01cc --- /dev/null +++ b/addons/medical_treatment/CfgReplacementItems.hpp @@ -0,0 +1,23 @@ +// This config accepts both item type numbers and item class names +// Item type numbers need the prefix ItemType_, so for example ItemType_401 +// Class names need no special prefix +class EGVAR(medical,replacementItems) { + DOUBLES(ItemType,TYPE_FIRST_AID_KIT)[] = { + {"ACE_fieldDressing", 1}, + {"ACE_packingBandage", 1}, + {"ACE_morphine", 1}, + {"ACE_tourniquet", 1} + }; + DOUBLES(ItemType,TYPE_MEDIKIT)[] = { + {"ACE_fieldDressing", 1}, + {"ACE_packingBandage", 2}, + {"ACE_epinephrine", 1}, + {"ACE_morphine", 1}, + {"ACE_salineIV_250", 1}, + {"ACE_tourniquet", 1}, + {"ACE_splint", 2} + }; + ACE_atropine[] = { + {"ACE_adenosine", 1} + }; +}; diff --git a/addons/medical_treatment/CfgVehicles.hpp b/addons/medical_treatment/CfgVehicles.hpp index 39940da4fc..d43c954da4 100644 --- a/addons/medical_treatment/CfgVehicles.hpp +++ b/addons/medical_treatment/CfgVehicles.hpp @@ -74,6 +74,9 @@ class CfgVehicles { class ACE_MedicalLitter_QuickClot: ACE_MedicalLitterBase { model = QPATHTOF(data\littergeneric_Quikclot.p3d); }; + class ACE_MedicalLitter_splint: ACE_MedicalLitterBase { + model = QPATHTOF(data\littergeneric_splint.p3d); + }; // Treatment items class Item_Base_F; @@ -117,6 +120,16 @@ class CfgVehicles { MACRO_ADDITEM(ACE_tourniquet,1); }; }; + class ACE_splintItem: Item_Base_F { + scope = 2; + scopeCurator = 2; + displayName = CSTRING(splint_Display); + author = ECSTRING(common,ACETeam); + vehicleClass = "Items"; + class TransportItems { + MACRO_ADDITEM(ACE_splint,1); + }; + }; class ACE_morphineItem: Item_Base_F { scope = 2; scopeCurator = 2; @@ -138,8 +151,8 @@ class CfgVehicles { }; }; class ACE_atropineItem: Item_Base_F { - scope = 2; - scopeCurator = 2; + scope = 1; + scopeCurator = 1; displayName = CSTRING(Atropine_Display); author = ECSTRING(common,ACETeam); vehicleClass = "Items"; @@ -292,9 +305,9 @@ class CfgVehicles { MACRO_ADDITEM(ACE_packingBandage,25); MACRO_ADDITEM(ACE_elasticBandage,25); MACRO_ADDITEM(ACE_tourniquet,15); + MACRO_ADDITEM(ACE_splint,15); MACRO_ADDITEM(ACE_morphine,15); MACRO_ADDITEM(ACE_adenosine,15); - MACRO_ADDITEM(ACE_atropine,15); MACRO_ADDITEM(ACE_epinephrine,15); MACRO_ADDITEM(ACE_plasmaIV,7); MACRO_ADDITEM(ACE_plasmaIV_500,7); diff --git a/addons/medical_treatment/CfgWeapons.hpp b/addons/medical_treatment/CfgWeapons.hpp index 17ed52fd4f..3e90457c8b 100644 --- a/addons/medical_treatment/CfgWeapons.hpp +++ b/addons/medical_treatment/CfgWeapons.hpp @@ -1,71 +1,79 @@ class CfgWeapons { class ItemCore; + class ACE_ItemCore; class CBA_MiscItem_ItemInfo; class InventoryFirstAidKitItem_Base_F; class MedikitItem; - // ITEMS class FirstAidKit: ItemCore { type = 0; - ace_arsenal_hide = 1; class ItemInfo: InventoryFirstAidKitItem_Base_F { mass = 4; }; }; class Medikit: ItemCore { type = 0; - ace_arsenal_hide = 1; class ItemInfo: MedikitItem { mass = 60; }; }; - class ACE_ItemCore; class ACE_fieldDressing: ACE_ItemCore { scope = 2; author = ECSTRING(common,ACETeam); model = QPATHTOF(data\bandage.p3d); - picture = QPATHTOF(ui\items\fieldDressing_x_ca.paa); + picture = QPATHTOF(ui\fieldDressing_ca.paa); displayName = CSTRING(Bandage_Basic_Display); descriptionShort = CSTRING(Bandage_Basic_Desc_Short); descriptionUse = CSTRING(Bandage_Basic_Desc_Use); class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 2; + mass = 1; }; }; class ACE_packingBandage: ACE_ItemCore { scope = 2; author = ECSTRING(common,ACETeam); displayName = CSTRING(Packing_Bandage_Display); - picture = QPATHTOF(ui\items\packingBandage_x_ca.paa); + picture = QPATHTOF(ui\packingBandage_ca.paa); model = QPATHTOF(data\packingbandage.p3d); descriptionShort = CSTRING(Packing_Bandage_Desc_Short); descriptionUse = CSTRING(Packing_Bandage_Desc_Use); class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 2; + mass = 1; }; }; class ACE_elasticBandage: ACE_ItemCore { scope = 2; author = ECSTRING(common,ACETeam); displayName = CSTRING(Bandage_Elastic_Display); - picture = QPATHTOF(ui\items\elasticBandage_x_ca.paa); + picture = QPATHTOF(ui\elasticBandage_ca.paa); model = "\A3\Structures_F_EPA\Items\Medical\Bandage_F.p3d"; descriptionShort = CSTRING(Bandage_Elastic_Desc_Short); descriptionUse = CSTRING(Bandage_Elastic_Desc_Use); class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 2; + mass = 1; }; }; class ACE_tourniquet: ACE_ItemCore { scope = 2; author = ECSTRING(common,ACETeam); displayName = CSTRING(Tourniquet_Display); - picture = QPATHTOF(ui\items\tourniquet_x_ca.paa); + picture = QPATHTOF(ui\tourniquet_ca.paa); model = QPATHTOF(data\tourniquet.p3d); descriptionShort = CSTRING(Tourniquet_Desc_Short); descriptionUse = CSTRING(Tourniquet_Desc_Use); + class ItemInfo: CBA_MiscItem_ItemInfo { + mass = 1; + }; + }; + class ACE_splint: ACE_ItemCore { + scope = 2; + author = ECSTRING(common,ACETeam); + displayName = CSTRING(splint_Display); + picture = QPATHTOF(ui\splint_ca.paa); + model = QPATHTOF(data\splint.p3d); + descriptionShort = CSTRING(splint_Desc_Short); class ItemInfo: CBA_MiscItem_ItemInfo { mass = 2; }; @@ -74,48 +82,48 @@ class CfgWeapons { scope = 2; author = ECSTRING(common,ACETeam); displayName = CSTRING(Morphine_Display); - picture = QPATHTOF(ui\items\morphine_x_ca.paa); + picture = QPATHTOF(ui\morphine_ca.paa); model = QPATHTOF(data\morphine.p3d); descriptionShort = CSTRING(Morphine_Desc_Short); descriptionUse = CSTRING(Morphine_Desc_Use); class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 2; + mass = 1; }; }; class ACE_adenosine: ACE_ItemCore { scope = 2; author = ECSTRING(common,ACETeam); displayName = CSTRING(Adenosine_Display); - picture = QPATHTOF(ui\items\adenosine_x_ca.paa); + picture = QPATHTOF(ui\adenosine_ca.paa); model = QPATHTOF(data\adenosine.p3d); descriptionShort = CSTRING(adenosine_Desc_Short); descriptionUse = CSTRING(adenosine_Desc_Use); class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 2; + mass = 1; }; }; class ACE_atropine: ACE_ItemCore { - scope = 2; + scope = 1; author = ECSTRING(common,ACETeam); displayName = CSTRING(Atropine_Display); - picture = QPATHTOF(ui\items\atropine_x_ca.paa); + picture = QPATHTOF(ui\atropine_ca.paa); model = QPATHTOF(data\atropine.p3d); descriptionShort = CSTRING(Atropine_Desc_Short); descriptionUse = CSTRING(Atropine_Desc_Use); class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 2; + mass = 1; }; }; class ACE_epinephrine: ACE_ItemCore { scope = 2; author = ECSTRING(common,ACETeam); displayName = CSTRING(Epinephrine_Display); - picture = QPATHTOF(ui\items\epinephrine_x_ca.paa); + picture = QPATHTOF(ui\epinephrine_ca.paa); model = QPATHTOF(data\epinephrine.p3d); descriptionShort = CSTRING(Epinephrine_Desc_Short); descriptionUse = CSTRING(Epinephrine_Desc_Use); class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 2; + mass = 1; }; }; @@ -125,8 +133,8 @@ class CfgWeapons { displayName = CSTRING(Plasma_IV); model = QPATHTOF(data\IVBag_1000ml.p3d); hiddenSelections[] = {"camo"}; - hiddenSelectionsTextures[] = { QPATHTOF(data\IVBag_plasma_1000ml_ca.paa) }; - picture = QPATHTOF(ui\items\plasmaIV_x_ca.paa); + hiddenSelectionsTextures[] = {QPATHTOF(data\IVBag_plasma_1000ml_ca.paa)}; + picture = QPATHTOF(ui\plasmaIV_ca.paa); descriptionShort = CSTRING(Plasma_IV_Desc_Short); descriptionUse = CSTRING(Plasma_IV_Desc_Use); class ItemInfo: CBA_MiscItem_ItemInfo { @@ -136,7 +144,7 @@ class CfgWeapons { class ACE_plasmaIV_500: ACE_plasmaIV { displayName = CSTRING(Plasma_IV_500); model = QPATHTOF(data\IVBag_500ml.p3d); - hiddenSelectionsTextures[] = { QPATHTOF(data\IVBag_plasma_500ml_ca.paa) }; + hiddenSelectionsTextures[] = {QPATHTOF(data\IVBag_plasma_500ml_ca.paa)}; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 5; }; @@ -144,7 +152,7 @@ class CfgWeapons { class ACE_plasmaIV_250: ACE_plasmaIV { displayName = CSTRING(Plasma_IV_250); model = QPATHTOF(data\IVBag_250ml.p3d); - hiddenSelectionsTextures[] = { QPATHTOF(data\IVBag_plasma_250ml_ca.paa) }; + hiddenSelectionsTextures[] = {QPATHTOF(data\IVBag_plasma_250ml_ca.paa)}; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 2.5; }; @@ -154,9 +162,9 @@ class CfgWeapons { author = ECSTRING(common,ACETeam); model = QPATHTOF(data\IVBag_1000ml.p3d); displayName = CSTRING(Blood_IV); - picture = QPATHTOF(ui\items\bloodIV_x_ca.paa); + picture = QPATHTOF(ui\bloodIV_ca.paa); hiddenSelections[] = {"camo"}; - hiddenSelectionsTextures[] = { QPATHTOF(data\IVBag_blood_1000ml_ca.paa) }; + hiddenSelectionsTextures[] = {QPATHTOF(data\IVBag_blood_1000ml_ca.paa)}; descriptionShort = CSTRING(Blood_IV_Desc_Short); descriptionUse = CSTRING(Blood_IV_Desc_Use); class ItemInfo: CBA_MiscItem_ItemInfo { @@ -166,7 +174,7 @@ class CfgWeapons { class ACE_bloodIV_500: ACE_bloodIV { displayName = CSTRING(Blood_IV_500); model = QPATHTOF(data\IVBag_500ml.p3d); - hiddenSelectionsTextures[] = { QPATHTOF(data\IVBag_blood_500ml_ca.paa) }; + hiddenSelectionsTextures[] = {QPATHTOF(data\IVBag_blood_500ml_ca.paa)}; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 5; }; @@ -174,7 +182,7 @@ class CfgWeapons { class ACE_bloodIV_250: ACE_bloodIV { displayName = CSTRING(Blood_IV_250); model = QPATHTOF(data\IVBag_250ml.p3d); - hiddenSelectionsTextures[] = { QPATHTOF(data\IVBag_blood_250ml_ca.paa) }; + hiddenSelectionsTextures[] = {QPATHTOF(data\IVBag_blood_250ml_ca.paa)}; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 2.5; }; @@ -185,8 +193,8 @@ class CfgWeapons { displayName = CSTRING(Saline_IV); model = QPATHTOF(data\IVBag_1000ml.p3d); hiddenSelections[] = {"camo"}; - hiddenSelectionsTextures[] = { QPATHTOF(data\IVBag_saline_1000ml_ca.paa) }; - picture = QPATHTOF(ui\items\salineIV_x_ca.paa); + hiddenSelectionsTextures[] = {QPATHTOF(data\IVBag_saline_1000ml_ca.paa)}; + picture = QPATHTOF(ui\salineIV_ca.paa); descriptionShort = CSTRING(Saline_IV_Desc_Short); descriptionUse = CSTRING(Saline_IV_Desc_Use); class ItemInfo: CBA_MiscItem_ItemInfo { @@ -196,7 +204,7 @@ class CfgWeapons { class ACE_salineIV_500: ACE_salineIV { displayName = CSTRING(Saline_IV_500); model = QPATHTOF(data\IVBag_500ml.p3d); - hiddenSelectionsTextures[] = { QPATHTOF(data\IVBag_saline_500ml_ca.paa) }; + hiddenSelectionsTextures[] = {QPATHTOF(data\IVBag_saline_500ml_ca.paa)}; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 5; }; @@ -204,7 +212,7 @@ class CfgWeapons { class ACE_salineIV_250: ACE_salineIV { displayName = CSTRING(Saline_IV_250); model = QPATHTOF(data\IVBag_250ml.p3d); - hiddenSelectionsTextures[] = { QPATHTOF(data\IVBag_saline_250ml_ca.paa) }; + hiddenSelectionsTextures[] = {QPATHTOF(data\IVBag_saline_250ml_ca.paa)}; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 2.5; }; @@ -214,18 +222,18 @@ class CfgWeapons { author = ECSTRING(common,ACETeam); displayName = CSTRING(QuikClot_Display); model = QPATHTOF(data\QuikClot.p3d); - picture = QPATHTOF(ui\items\quickclot_x_ca.paa); + picture = QPATHTOF(ui\quickclot_ca.paa); descriptionShort = CSTRING(QuikClot_Desc_Short); descriptionUse = CSTRING(QuikClot_Desc_Use); class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 2; + mass = 1; }; }; class ACE_personalAidKit: ACE_ItemCore { scope = 2; author = ECSTRING(common,ACETeam); displayName = CSTRING(Aid_Kit_Display); - picture = QPATHTOF(ui\items\personal_aid_kit_x_ca.paa); + picture = QPATHTOF(ui\personal_aid_kit_ca.paa); descriptionShort = CSTRING(Aid_Kit_Desc_Short); descriptionUse = CSTRING(Aid_Kit_Desc_Use); class ItemInfo: CBA_MiscItem_ItemInfo { @@ -233,11 +241,11 @@ class CfgWeapons { }; }; class ACE_surgicalKit: ACE_ItemCore { - scope=2; + scope = 2; author = ECSTRING(common,ACETeam); displayName= CSTRING(SurgicalKit_Display); model = QPATHTOF(data\surgical_kit.p3d); - picture = QPATHTOF(ui\items\surgicalKit_x_ca.paa); + picture = QPATHTOF(ui\surgicalKit_ca.paa); descriptionShort = CSTRING(SurgicalKit_Desc_Short); descriptionUse = CSTRING(SurgicalKit_Desc_Use); class ItemInfo: CBA_MiscItem_ItemInfo { @@ -245,11 +253,11 @@ class CfgWeapons { }; }; class ACE_bodyBag: ACE_ItemCore { - scope=2; + scope = 2; author = ECSTRING(common,ACETeam); displayName= CSTRING(Bodybag_Display); model = QPATHTOF(data\bodybagItem.p3d); - picture = QPATHTOF(ui\items\bodybag_x_ca.paa); + picture = QPATHTOF(ui\bodybag_ca.paa); descriptionShort = CSTRING(Bodybag_Desc_Short); descriptionUse = CSTRING(Bodybag_Desc_Use); class ItemInfo: CBA_MiscItem_ItemInfo { diff --git a/addons/medical_treatment/XEH_PREP.hpp b/addons/medical_treatment/XEH_PREP.hpp index 77e91fbc2a..480a65f2cb 100644 --- a/addons/medical_treatment/XEH_PREP.hpp +++ b/addons/medical_treatment/XEH_PREP.hpp @@ -1,71 +1,62 @@ - -// actions -PREP(actionCheckBloodPressure); -PREP(actionCheckBloodPressureLocal); -PREP(actionCheckPulse); -PREP(actionCheckPulseLocal); -PREP(actionCheckResponse); -PREP(actionDiagnose); -PREP(actionLoadUnit); -PREP(actionPlaceInBodyBag); -PREP(actionUnloadUnit); PREP(addLoadPatientActions); - -// treaments -PREP(canTreat); -PREP(canTreatCached); -PREP(treatment); -PREP(treatment_failure); -PREP(treatment_success); - -PREP(treatmentBandage); -PREP(treatmentBandageLocal); -PREP(treatmentCPR); -PREP(treatmentCPR_failure); -PREP(treatmentCPR_progress); -PREP(treatmentCPR_start); -PREP(treatmentCPRLocal); -PREP(treatmentFullHeal); -PREP(treatmentFullHealLocal); -PREP(treatmentIV); -PREP(treatmentIVLocal); -PREP(treatmentMedication); -PREP(treatmentMedicationLocal); -PREP(treatmentSurgicalKit_onProgress); -PREP(treatmentTourniquet); -PREP(treatmentTourniquetLocal); -PREP(treatmentTourniquetRemove); - -// misc PREP(addToLog); PREP(addToTriageCard); +PREP(bandage); +PREP(bandageLocal); PREP(bodyCleanupLoop); -PREP(calculateBlood); -PREP(canAccessMedicalEquipment); PREP(canBandage); +PREP(canCPR); +PREP(canSplint); PREP(canStitch); +PREP(canTreat); +PREP(canTreatCached); +PREP(canTreat_holsterCheck); +PREP(checkBloodPressure); +PREP(checkBloodPressureLocal); +PREP(checkPulse); +PREP(checkPulseLocal); +PREP(checkResponse); +PREP(cprSuccess); +PREP(cprFailure); +PREP(cprLocal); +PREP(cprProgress); +PREP(cprStart); +PREP(createLitter); +PREP(createLitterServer); +PREP(diagnose); PREP(findMostEffectiveWound); +PREP(fullHeal); +PREP(fullHealLocal); PREP(getBandageTime); +PREP(getHealTime); +PREP(getStitchableWounds); +PREP(getStitchTime); PREP(getTriageStatus); PREP(handleBandageOpening); +PREP(hasItem); PREP(hasTourniquetAppliedTo); -PREP(healTime); PREP(isInMedicalFacility); PREP(isInMedicalVehicle); PREP(isMedic); PREP(isMedicalVehicle); -PREP(onMedicationUsage); -PREP(serverRemoveBody); -PREP(setTriageStatus); - -// items -PREP(checkItems); -PREP(hasItem); -PREP(hasItems); -PREP(useItem); -PREP(useItems); - -// litter +PREP(ivBag); +PREP(ivBagLocal); PREP(litterCleanupLoop); -PREP(litterCreate); -PREP(litterHandleCreate); +PREP(loadUnit); +PREP(medication); +PREP(medicationLocal); +PREP(onMedicationUsage); +PREP(placeInBodyBag); +PREP(removeBody); +PREP(setTriageStatus); +PREP(splint); +PREP(splintLocal); +PREP(surgicalKitProgress); +PREP(tourniquet); +PREP(tourniquetLocal); +PREP(tourniquetRemove); +PREP(treatment); +PREP(treatmentFailure); +PREP(treatmentSuccess); +PREP(unloadUnit); +PREP(useItem); diff --git a/addons/medical_treatment/XEH_postInit.sqf b/addons/medical_treatment/XEH_postInit.sqf index ecaca5cea6..413f96cd43 100644 --- a/addons/medical_treatment/XEH_postInit.sqf +++ b/addons/medical_treatment/XEH_postInit.sqf @@ -1,27 +1,63 @@ #include "script_component.hpp" -[QEGVAR(medical_status,initialized), FUNC(checkItems)] call CBA_fnc_addEventHandler; -["loadout", FUNC(checkItems)] call CBA_fnc_addPlayerEventHandler; +[QEGVAR(medical_status,initialized), { + params ["_unit"]; -// Handle bodybags and litter on server + // Clear all saved medical logs + { + _unit setVariable [_x, nil, true]; + } forEach (_unit getVariable [QEGVAR(medical,allLogs), []]); + + _unit setVariable [QEGVAR(medical,allLogs), [], true]; +}] call CBA_fnc_addEventHandler; + +// Handle body removal and litter on server if (isServer) then { - [QGVAR(createLitterServer), FUNC(litterHandleCreate)] call CBA_fnc_addEventHandler; - ["ace_placedInBodyBag", FUNC(serverRemoveBody)] call CBA_fnc_addEventHandler; + [QGVAR(createLitterServer), LINKFUNC(createLitterServer)] call CBA_fnc_addEventHandler; + ["ace_placedInBodyBag", LINKFUNC(removeBody)] call CBA_fnc_addEventHandler; }; -// treatment events -[QGVAR(treatmentBandageLocal), FUNC(treatmentBandageLocal)] call CBA_fnc_addEventHandler; -[QGVAR(treatmentTourniquetLocal), FUNC(treatmentTourniquetLocal)] call CBA_fnc_addEventHandler; -[QGVAR(treatmentMedicationLocal), FUNC(treatmentMedicationLocal)] call CBA_fnc_addEventHandler; -[QGVAR(treatmentIVLocal), FUNC(treatmentIVLocal)] call CBA_fnc_addEventHandler; -[QGVAR(treatmentCPRLocal), FUNC(treatmentCPRLocal)] call CBA_fnc_addEventHandler; -[QGVAR(treatmentFullHealLocal), FUNC(treatmentFullHealLocal)] call CBA_fnc_addEventHandler; +// Treatment events +[QGVAR(bandageLocal), LINKFUNC(bandageLocal)] call CBA_fnc_addEventHandler; +[QGVAR(checkBloodPressureLocal), LINKFUNC(checkBloodPressureLocal)] call CBA_fnc_addEventHandler; +[QGVAR(checkPulseLocal), LINKFUNC(checkPulseLocal)] call CBA_fnc_addEventHandler; +[QGVAR(cprLocal), LINKFUNC(cprLocal)] call CBA_fnc_addEventHandler; +[QGVAR(fullHealLocal), LINKFUNC(fullHealLocal)] call CBA_fnc_addEventHandler; +[QGVAR(ivBagLocal), LINKFUNC(ivBagLocal)] call CBA_fnc_addEventHandler; +[QGVAR(medicationLocal), LINKFUNC(medicationLocal)] call CBA_fnc_addEventHandler; +[QGVAR(placeInBodyBag), LINKFUNC(placeInBodyBag)] call CBA_fnc_addEventHandler; +[QGVAR(splintLocal), LINKFUNC(splintLocal)] call CBA_fnc_addEventHandler; +[QGVAR(tourniquetLocal), LINKFUNC(tourniquetLocal)] call CBA_fnc_addEventHandler; -// action events -[QGVAR(actionCheckPulseLocal), FUNC(actionCheckPulseLocal)] call CBA_fnc_addEventHandler; -[QGVAR(actionCheckBloodPressureLocal), FUNC(actionCheckBloodPressureLocal)] call CBA_fnc_addEventHandler; -[QGVAR(actionPlaceInBodyBag), FUNC(actionPlaceInBodyBag)] call CBA_fnc_addEventHandler; +// Logging events +[QGVAR(addToLog), LINKFUNC(addToLog)] call CBA_fnc_addEventHandler; +[QGVAR(addToTriageCard), LINKFUNC(addToTriageCard)] call CBA_fnc_addEventHandler; -// log events -[QGVAR(addToMedicalLog), FUNC(addToLog)] call CBA_fnc_addEventHandler; -[QGVAR(addToTriageCard), FUNC(addToTriageCard)] call CBA_fnc_addEventHandler; +// replace medical items with their ACE equivalents +["ace_settingsInitialized", { + TRACE_1("ace_settingsInitialized EH",GVAR(convertItems)); // 0: Enabled 1: RemoveOnly 2:Disabled + if (GVAR(convertItems) == 2) exitWith {}; + { + // turn [["stuff", 2], ...] into ["stuff", "stuff", ...] + private _replacements = []; + if (GVAR(convertItems) == 0) then { + { + _x params ["_item", "_count"]; + for "_i" from 1 to _count do { + _replacements pushBack _item; + }; + } forEach getArray _x; + }; + + // check if replacement is for item type or class name + private _configName = configName _x; + private _toReplace = if ((_configName select [0,9]) == "ItemType_") then { + parseNumber (_configName select [9]) + } else { + _configName + }; + + // register replacement + [_toReplace, _replacements] call EFUNC(common,registerItemReplacement); + } forEach (configProperties [configFile >> QEGVAR(medical,replacementItems), "isArray _x"]); +}] call CBA_fnc_addEventHandler; diff --git a/addons/medical_treatment/XEH_preInit.sqf b/addons/medical_treatment/XEH_preInit.sqf index a4ddb9f082..dfb6bf6518 100644 --- a/addons/medical_treatment/XEH_preInit.sqf +++ b/addons/medical_treatment/XEH_preInit.sqf @@ -31,7 +31,17 @@ GVAR(animDurations) = [] call CBA_fnc_createNamespace; ["AinvPknlMstpSlayWlnrDnon_medicOther", 9], ["AinvPknlMstpSlayWpstDnon_medicOther", 10], ["AinvPpneMstpSlayWpstDnon_medicOther", 8.5], - ["AinvPknlMstpSnonWnonDnon_medic1", 10] + ["AinvPknlMstpSnonWnonDnon_medic1", 10], + ["AinvPknlMstpSnonWnonDr_medic0", 12] ]; +// class names of medical facilities (config case) +GVAR(facilityClasses) = []; +{ + { + private _name = configName (configFile >> "CfgVehicles" >> _x); + if (_name != "") then { GVAR(facilityClasses) pushBackUnique _name; }; + } forEach getArray _x; +} forEach configProperties [configFile >> QEGVAR(medical,facilities), "isArray _x"]; + ADDON = true; diff --git a/addons/medical_treatment/config.cpp b/addons/medical_treatment/config.cpp index 30ea36a861..29c11c18ad 100644 --- a/addons/medical_treatment/config.cpp +++ b/addons/medical_treatment/config.cpp @@ -16,8 +16,9 @@ class CfgPatches { #include "ACE_Medical_Treatment.hpp" #include "ACE_Medical_Treatment_Actions.hpp" -#include "ACE_Settings.hpp" -#include "CfgEden.hpp" +#include "ACE_Medical_Facilities.hpp" #include "CfgEventHandlers.hpp" +#include "CfgReplacementItems.hpp" #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" +#include "Cfg3DEN.hpp" diff --git a/addons/medical_treatment/data/littergeneric_splint.p3d b/addons/medical_treatment/data/littergeneric_splint.p3d new file mode 100644 index 0000000000..4918cacaf4 Binary files /dev/null and b/addons/medical_treatment/data/littergeneric_splint.p3d differ diff --git a/addons/medical_treatment/data/model.cfg b/addons/medical_treatment/data/model.cfg index 58f288c3b9..344141e28e 100644 --- a/addons/medical_treatment/data/model.cfg +++ b/addons/medical_treatment/data/model.cfg @@ -47,6 +47,7 @@ class CfgModels { class bandage: Default {}; class bodybagItem: Default {}; class epinephrine: Default {}; + class splint: Default {}; class IVBagBase: Default { sectionsInherit = ""; @@ -69,6 +70,7 @@ class CfgModels { class littergeneric_morphine: Default {}; class littergeneric_packingbandage: Default {}; class littergeneric_Quikclot: Default {}; + class littergeneric_splint: Default {}; class morphine: Default {}; class packingbandage: Default {}; class QuikClot: Default {}; diff --git a/addons/medical_treatment/data/splint.p3d b/addons/medical_treatment/data/splint.p3d new file mode 100644 index 0000000000..20cbe0a5d0 Binary files /dev/null and b/addons/medical_treatment/data/splint.p3d differ diff --git a/addons/medical_treatment/data/splint.rvmat b/addons/medical_treatment/data/splint.rvmat new file mode 100644 index 0000000000..69af44f738 --- /dev/null +++ b/addons/medical_treatment/data/splint.rvmat @@ -0,0 +1,92 @@ +ambient[]={1,1,1,1}; +diffuse[]={1,1,1,1}; +forcedDiffuse[]={0,0,0,0}; +emmisive[]={0,0,0,1}; +specular[]={1,1,1,0}; +specularPower=50; +PixelShaderID="Super"; +VertexShaderID="Super"; +class Stage1 +{ + texture="z\ace\addons\medical_treatment\data\splint_nohq.paa"; + uvSource="tex"; + 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,1,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,MC)"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage4 +{ + texture="z\ace\addons\medical_treatment\data\splint_as.paa"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage5 +{ + texture="z\ace\addons\medical_treatment\data\splint_smdi.paa"; + uvSource="tex"; + 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(2,0.1)"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage7 +{ + texture="a3\data_f\env_land_co.paa"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; diff --git a/addons/medical_treatment/data/splint_as.paa b/addons/medical_treatment/data/splint_as.paa new file mode 100644 index 0000000000..810525bdab Binary files /dev/null and b/addons/medical_treatment/data/splint_as.paa differ diff --git a/addons/medical_treatment/data/splint_ca.paa b/addons/medical_treatment/data/splint_ca.paa new file mode 100644 index 0000000000..cff2ab6ff8 Binary files /dev/null and b/addons/medical_treatment/data/splint_ca.paa differ diff --git a/addons/medical_treatment/data/splint_nohq.paa b/addons/medical_treatment/data/splint_nohq.paa new file mode 100644 index 0000000000..2ed96ef112 Binary files /dev/null and b/addons/medical_treatment/data/splint_nohq.paa differ diff --git a/addons/medical_treatment/data/splint_smdi.paa b/addons/medical_treatment/data/splint_smdi.paa new file mode 100644 index 0000000000..e9c4efb07b Binary files /dev/null and b/addons/medical_treatment/data/splint_smdi.paa differ diff --git a/addons/medical_treatment/functions/fnc_actionCheckBloodPressure.sqf b/addons/medical_treatment/functions/fnc_actionCheckBloodPressure.sqf deleted file mode 100644 index 6c5c17a151..0000000000 --- a/addons/medical_treatment/functions/fnc_actionCheckBloodPressure.sqf +++ /dev/null @@ -1,21 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal - * Action for checking the blood pressure of the patient - * - * Arguments: - * 0: The medic - * 1: The patient - * 2: Body part - * - * Return Value: - * None - * - * Public: No - */ - -params ["_caller", "_target", "_bodyPart"]; - -[QGVAR(actionCheckBloodPressureLocal), [_caller, _target, _bodyPart], _target] call CBA_fnc_targetEvent; - -true diff --git a/addons/medical_treatment/functions/fnc_actionCheckBloodPressureLocal.sqf b/addons/medical_treatment/functions/fnc_actionCheckBloodPressureLocal.sqf deleted file mode 100644 index c0a995e3cd..0000000000 --- a/addons/medical_treatment/functions/fnc_actionCheckBloodPressureLocal.sqf +++ /dev/null @@ -1,57 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal - * Local callback for checking the blood pressure of a patient - * - * Arguments: - * 0: The medic - * 1: The patient - * 2: Body part - * - * Return Value: - * None - * - * Public: No - */ - -params ["_caller", "_target", "_bodyPart"]; - -private _bloodPressure = [0, 0]; - -if (alive _target && {!([_target, _bodyPart] call FUNC(hasTourniquetAppliedTo))}) then { - _bloodPressure = GET_BLOOD_PRESSURE(_target); -}; - -private _bloodPressureOutput = ELSTRING(medical_treatment,Check_Bloodpressure_Output_6); -private _logOutPut = ELSTRING(medical_treatment,Check_Bloodpressure_NoBloodpressure); - -_bloodPressure params ["_bloodPressureLow", "_bloodPressureHigh"]; - -if (_bloodPressureHigh > 20) then { - if (_caller call FUNC(isMedic)) then { - _bloodPressureOutput = ELSTRING(medical_treatment,Check_Bloodpressure_Output_1); - _logOutPut = format ["%1/%2", round _bloodPressureHigh, round _bloodPressureLow]; - } else { - if (_bloodPressureHigh > 20) then { - _bloodPressureOutput = ELSTRING(medical_treatment,Check_Bloodpressure_Output_2); - _logOutPut = ELSTRING(medical_treatment,Check_Bloodpressure_Low); - - if (_bloodPressureHigh > 100) then { - _bloodPressureOutput = ELSTRING(medical_treatment,Check_Bloodpressure_Output_3); - _logOutPut = ELSTRING(medical_treatment,Check_Bloodpressure_Normal); - - if (_bloodPressureHigh > 160) then { - _bloodPressureOutput = ELSTRING(medical_treatment,Check_Bloodpressure_Output_4); - _logOutPut = ELSTRING(medical_treatment,Check_Bloodpressure_High); - }; - }; - }; - }; -}; - -[QEGVAR(common,displayTextStructured), [[_bloodPressureOutput, _target call EFUNC(common,getName), round _bloodPressureHigh, round _bloodPressureLow], 1.75, _caller], _caller] call CBA_fnc_targetEvent; - -if (_logOutPut != "") then { - [_target, "activity", ELSTRING(medical_treatment,Check_Bloodpressure_Log), [_caller call EFUNC(common,getName), _logOutPut]] call FUNC(addToLog); - [_target, "quick_view", ELSTRING(medical_treatment,Check_Bloodpressure_Log), [_caller call EFUNC(common,getName), _logOutPut]] call FUNC(addToLog); -}; diff --git a/addons/medical_treatment/functions/fnc_actionCheckPulse.sqf b/addons/medical_treatment/functions/fnc_actionCheckPulse.sqf deleted file mode 100644 index 29afe8a60e..0000000000 --- a/addons/medical_treatment/functions/fnc_actionCheckPulse.sqf +++ /dev/null @@ -1,21 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal - * Action for checking the pulse or heart rate of the patient - * - * Arguments: - * 0: The medic - * 1: The patient - * 2: Body part - * - * Return Value: - * None - * - * Public: No - */ - -params ["_caller", "_target", "_bodyPart"]; - -[QGVAR(actionCheckPulseLocal), [_caller, _target, _bodyPart], _target] call CBA_fnc_targetEvent; - -true diff --git a/addons/medical_treatment/functions/fnc_actionCheckPulseLocal.sqf b/addons/medical_treatment/functions/fnc_actionCheckPulseLocal.sqf deleted file mode 100644 index 585ba4c7d8..0000000000 --- a/addons/medical_treatment/functions/fnc_actionCheckPulseLocal.sqf +++ /dev/null @@ -1,54 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal - * Local callback for checking the pulse of a patient - * - * Arguments: - * 0: The medic - * 1: The patient - * 2: Body part - * - * Return Value: - * None - * - * Public: No - */ - -params ["_caller", "_target", "_bodyPart"]; - -private _heartRate = 0; - -if (alive _target && {!([_target, _bodyPart] call FUNC(hasTourniquetAppliedTo))}) then { - _heartRate = GET_HEART_RATE(_target); -}; - -private _heartRateOutput = ELSTRING(medical_treatment,Check_Pulse_Output_5); -private _logOutPut = ELSTRING(medical_treatment,Check_Pulse_None); - -if (_heartRate > 1.0) then { - if (_caller call FUNC(isMedic)) then { - _heartRateOutput = ELSTRING(medical_treatment,Check_Pulse_Output_1); - _logOutPut = format ["%1", round(_heartRate)]; - } else { - // non medical personel will only find a pulse/HR - _heartRateOutput = ELSTRING(medical_treatment,Check_Pulse_Output_2); - _logOutPut = ELSTRING(medical_treatment,Check_Pulse_Weak); - - if (_heartRate > 60) then { - if (_heartRate > 100) then { - _heartRateOutput = ELSTRING(medical_treatment,Check_Pulse_Output_3); - _logOutPut = ELSTRING(medical_treatment,Check_Pulse_Strong); - } else { - _heartRateOutput = ELSTRING(medical_treatment,Check_Pulse_Output_4); - _logOutPut = ELSTRING(medical_treatment,Check_Pulse_Normal); - }; - }; - }; -}; - -[QEGVAR(common,displayTextStructured), [[_heartRateOutput, _target call EFUNC(common,getName), round _heartRate], 1.5, _caller], _caller] call CBA_fnc_targetEvent; - -if (_logOutPut != "") then { - [_target, "activity", ELSTRING(medical_treatment,Check_Pulse_Log), [_caller call EFUNC(common,getName), _logOutPut]] call FUNC(addToLog); - [_target, "quick_view", ELSTRING(medical_treatment,Check_Pulse_Log), [_caller call EFUNC(common,getName), _logOutPut]] call FUNC(addToLog); -}; diff --git a/addons/medical_treatment/functions/fnc_actionCheckResponse.sqf b/addons/medical_treatment/functions/fnc_actionCheckResponse.sqf deleted file mode 100644 index 7bf7cf7c5c..0000000000 --- a/addons/medical_treatment/functions/fnc_actionCheckResponse.sqf +++ /dev/null @@ -1,26 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal - * Action for checking the response status of the patient - * - * Arguments: - * 0: The medic - * 1: The patient - * - * Return Value: - * None - * - * Example: - * [bob, kevin] call ace_medical_treatment_fnc_actionCheckResponse - * - * Public: No - */ - -params ["_caller", "_target"]; - -private _output = [ELSTRING(medical_treatment,Check_Response_Unresponsive), ELSTRING(medical_treatment,Check_Response_Responsive)] select (_target call EFUNC(common,isAwake)); - -[QEGVAR(common,displayTextStructured), [[_output, _target call EFUNC(common,getName)], 2, _caller], _caller] call CBA_fnc_targetEvent; - -[_target ,"activity", _output, [[_target, false, true] call EFUNC(common,getName)]] call FUNC(addToLog); -[_target, "quick_view", _output, [[_target, false, true] call EFUNC(common,getName)]] call FUNC(addToLog); diff --git a/addons/medical_treatment/functions/fnc_actionDiagnose.sqf b/addons/medical_treatment/functions/fnc_actionDiagnose.sqf deleted file mode 100644 index 6e9eda9610..0000000000 --- a/addons/medical_treatment/functions/fnc_actionDiagnose.sqf +++ /dev/null @@ -1,45 +0,0 @@ -#include "script_component.hpp" -/* -* Author: Glowbal -* Action for diagnosing in basic medical -* -* Arguments: -* 0: The medic -* 1: The patient -* -* Return Value: -* None -* -* Public: No -*/ - -params ["_caller", "_target"]; - -private _genericMessages = [ELSTRING(medical_treatment,diagnoseMessage), _target call EFUNC(common,getName)]; - -if (alive _target) then { - _genericMessages pushBack ELSTRING(medical_treatment,diagnoseAlive); -} else { - _genericMessages pushBack ELSTRING(medical_treatment,diagnoseDead); -}; - -private _hemorrhage = GET_HEMORRHAGE(_target); -if (_hemorrhage > 0) then { - if (_hemorrhage > 1) then { - _genericMessages pushBack ELSTRING(medical_treatment,lostBloodALot); - } else { - _genericMessages pushBack ELSTRING(medical_treatment,lostBlood); - }; -} else { - _genericMessages pushBack ELSTRING(medical_treatment,noBloodloss); -}; - -if (alive _target) then { - if IS_IN_PAIN(_target) then { - _genericMessages pushBack ELSTRING(medical_treatment,inPain); - } else { - _genericMessages pushBack ELSTRING(medical_treatment,noPain); - }; -}; - -[QEGVAR(common,displayTextStructured), [_genericMessages, 3.0, _caller], _caller] call CBA_fnc_targetEvent; diff --git a/addons/medical_treatment/functions/fnc_actionLoadUnit.sqf b/addons/medical_treatment/functions/fnc_actionLoadUnit.sqf deleted file mode 100644 index d4e6b57dc4..0000000000 --- a/addons/medical_treatment/functions/fnc_actionLoadUnit.sqf +++ /dev/null @@ -1,42 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal - * Action for loading an unconscious or dead unit in the nearest vehicle, or _vehicle if given. - * - * Arguments: - * 0: The medic - * 1: The patient - * 2: The vehicle (default: objNull) - * - * Return Value: - * Vehicle they are loaded into (objNull on failure) - * - * Example: - * [bob, kevin] call ace_medical_treatment_treatment_fnc_actionLoadUnit - * - * Public: No - */ - -params ["_caller", "_target", ["_vehicle", objNull]]; - -if ([_target] call EFUNC(common,isAwake)) exitWith { - [QEGVAR(common,displayTextStructured), [[ELSTRING(medical,CanNotLoaded), _target call EFUNC(common,getName)], 1.5, _caller], _caller] call CBA_fnc_targetEvent; -}; - -if ([_target] call EFUNC(medical_status,isBeingCarried)) then { - [_caller, _target] call EFUNC(dragging,dropObject_carry); -}; - -if ([_target] call EFUNC(medical_status,isBeingDragged)) then { - [_caller, _target] call EFUNC(dragging,dropObject); -}; - -private _vehicle = [_caller, _target, _vehicle] call EFUNC(common,loadPerson); -if (!isNull _vehicle) then { - private _hint = LSTRING(loadedInto); - private _itemName = [_target, false, true] call EFUNC(common,getName); - private _vehicleName = getText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "displayName"); - [[_hint, _itemName, _vehicleName], 3.0] call EFUNC(common,displayTextStructured); -}; - -_vehicle diff --git a/addons/medical_treatment/functions/fnc_actionPlaceInBodyBag.sqf b/addons/medical_treatment/functions/fnc_actionPlaceInBodyBag.sqf deleted file mode 100644 index 0069e74e67..0000000000 --- a/addons/medical_treatment/functions/fnc_actionPlaceInBodyBag.sqf +++ /dev/null @@ -1,51 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal - * Replace a (dead) body by a body bag - * - * Arguments: - * 0: The actor - * 1: The patient - * - * Return Value: - * body bag (will return objNull when run where target is not local) - * - * Example: - * [player, cursorTarget] call ace_medical_treatment_fnc_actionPlaceInBodyBag - * - * Public: No - */ - -params ["_caller", "_target"]; -TRACE_2("params",_caller,_target); - -if (!local _target) exitWith { - TRACE_1("running where local",local _target); - [QGVAR(actionPlaceInBodyBag), [_caller, _target], _target] call CBA_fnc_targetEvent; - objNull -}; - -if (alive _target) then { - TRACE_1("manually killing with setDead",_target); - [_target, true, "buried_alive"] call EFUNC(medical_status,setDead); -}; - -private _position = (getPosASL _target) vectorAdd [0, 0, 0.2]; - -private _headPos = _target modelToWorldVisual (_target selectionPosition "head"); -private _spinePos = _target modelToWorldVisual (_target selectionPosition "Spine3"); -private _dirVect = _headPos vectorFromTo _spinePos; -private _direction = _dirVect call CBA_fnc_vectDir; - -// move the body away now, so it won't physX the bodyBag object (this setPos seems to need to be called where object is local) -_target setPosASL [-5000, -5000, 0]; - -private _bodyBag = createVehicle ["ACE_bodyBagObject", _position, [], 0, "NONE"]; - -// prevent body bag from flipping -_bodyBag setPosASL _position; -_bodyBag setDir _direction; - -["ace_placedInBodyBag", [_target, _bodyBag]] call CBA_fnc_globalEvent; // hide and delete body on server - -_bodyBag diff --git a/addons/medical_treatment/functions/fnc_actionUnloadUnit.sqf b/addons/medical_treatment/functions/fnc_actionUnloadUnit.sqf deleted file mode 100644 index d69b2a7c64..0000000000 --- a/addons/medical_treatment/functions/fnc_actionUnloadUnit.sqf +++ /dev/null @@ -1,26 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal - * Action for unloading an unconscious or dead unit from a vechile - * - * Arguments: - * 0: The medic - * 1: The patient - * 2: Drag after unload (default: false) - * - * Return Value: - * None - * - * Example: - * [bob, kevin, false] call ace_medical_treatment_fnc_actionUnloadUnit - * - * Public: No - */ - -params ["_caller", "_target", ["_drag", false]]; - -// cannot unload a unit not in a vehicle. -if (vehicle _target == _target) exitWith {WARNING_1("Unit [%1] not in vehicle",_target);}; -if (_target call EFUNC(common,isAwake)) exitWith {WARNING_1("Unit [%1] is awake",_target);}; - -["ace_unloadPersonEvent", [_target, vehicle _target, _caller], _target] call CBA_fnc_targetEvent; diff --git a/addons/medical_treatment/functions/fnc_addLoadPatientActions.sqf b/addons/medical_treatment/functions/fnc_addLoadPatientActions.sqf index 3448793847..fe97152c92 100644 --- a/addons/medical_treatment/functions/fnc_addLoadPatientActions.sqf +++ b/addons/medical_treatment/functions/fnc_addLoadPatientActions.sqf @@ -1,16 +1,16 @@ #include "script_component.hpp" /* * Author: 654wak654 - * Adds child actions to the "load patient" action for near vehicles. + * Returns children actions to the "Load Patient" action for nearby vehicles. * * Arguments: * 0: Patient * * Return Value: - * Child actions + * Actions * * Example: - * [kevin] call ace_medical_treatment_fnc_addLoadPatientActions + * [cursorObject] call ace_medical_treatment_fnc_addLoadPatientActions * * Public: No */ @@ -19,7 +19,7 @@ params ["_target"]; private _statement = { params ["_target", "_player", "_vehicle"]; - [_player, _target, _vehicle] call FUNC(actionLoadUnit); + [_player, _target, _vehicle] call FUNC(loadUnit); }; [_target call EFUNC(common,nearestVehiclesFreeSeat), _statement, _target] call EFUNC(interact_menu,createVehiclesActions) diff --git a/addons/medical_treatment/functions/fnc_addToLog.sqf b/addons/medical_treatment/functions/fnc_addToLog.sqf index 077cfc73ab..b250fec9b1 100644 --- a/addons/medical_treatment/functions/fnc_addToLog.sqf +++ b/addons/medical_treatment/functions/fnc_addToLog.sqf @@ -1,56 +1,45 @@ #include "script_component.hpp" /* - * Author: Glowbal - * Add an entry to the specified log + * Author: Glowbal, mharis001 + * Adds an entry to the specified medical log of the unit. * * Arguments: - * 0: The patient - * 1: The log type - * 2: The message - * 3: The arguments for localization + * 0: Unit + * 1: Log Type + * 2: Message + * 3: Formatting Arguments * * Return Value: * None * * Example: - * [bob, "type", "message", [_args]] call ace_medical_treatment_fnc_addToLog + * [player, "activity", "Message %1", ["Name"]] call ace_medical_treatment_fnc_addToLog * * Public: No */ -params ["_unit", "_type", "_message", "_arguments"]; +params ["_unit", "_logType", "_message", "_arguments"]; if (!local _unit) exitWith { - [QGVAR(addToMedicalLog), _this, _unit] call CBA_fnc_targetEvent; + [QGVAR(addToLog), _this, _unit] call CBA_fnc_targetEvent; }; date params ["", "", "", "_hour", "_minute"]; +private _timeStamp = format ["%1:%2", _hour, [_minute, 2] call CBA_fnc_formatNumber]; -private _moment = format [["%1:%2", "%1:0%2"] select (_minute < 10), _hour, _minute]; -private _logVarName = format [QEGVAR(medical,logFile_%1), _type]; +private _logVarName = MED_LOG_VARNAME(_logType); private _log = _unit getVariable [_logVarName, []]; -if (count _log >= 8) then { - private _newLog = []; - - { - // ensure the first element will not be added - if (_forEachIndex > 0) then { - _newLog pushBack _x; - }; - } forEach _log; - - _log = _newLog; +if (count _log >= MED_LOG_MAX_ENTRIES) then { + _log deleteAt 0; }; -_log pushBack [_message, _moment, _type, _arguments]; - +_log pushBack [_message, _timeStamp, _arguments, _logType]; _unit setVariable [_logVarName, _log, true]; -["ace_medicalLogEntryAdded", [_unit, _type, _message, _arguments]] call CBA_fnc_localEvent; -private _logs = _unit getVariable [QEGVAR(medical,allLogs), []]; +private _allLogs = _unit getVariable [QEGVAR(medical,allLogs), []]; -if !(_logVarName in _logs) then { - _logs pushBack _logVarName; - _unit setVariable [QEGVAR(medical,allLogs), _logs, true]; +if !(_logVarName in _allLogs) then { + _allLogs pushBack _logVarName; + _unit setVariable [QEGVAR(medical,allLogs), _allLogs, true]; }; diff --git a/addons/medical_treatment/functions/fnc_addToTriageCard.sqf b/addons/medical_treatment/functions/fnc_addToTriageCard.sqf index 3d67d3288c..75cbc76b26 100644 --- a/addons/medical_treatment/functions/fnc_addToTriageCard.sqf +++ b/addons/medical_treatment/functions/fnc_addToTriageCard.sqf @@ -1,46 +1,37 @@ #include "script_component.hpp" /* - * Author: Glowbal - * Add an entry to the triage card + * Author: Glowbal, mharis001 + * Adds an entry to the unit's triage card. * * Arguments: - * 0: The patient - * 1: The new item class name + * 0: Unit + * 1: Item Classname * * Return Value: * None * * Example: - * [bob, "bandage"] call ace_medical_treatment_fnc_addToTriageCard + * [player, "ACE_morphine"] call ace_medical_treatment_fnc_addToTriageCard * * Public: No */ -params ["_unit", "_newItem"]; +params ["_unit", "_item"]; if (!local _unit) exitWith { [QGVAR(addToTriageCard), _this, _unit] call CBA_fnc_targetEvent; }; -private _log = _unit getVariable [QEGVAR(medical,triageCard), []]; -private _inList = false; -private _amount = 1; +private _triageCard = _unit getVariable [QEGVAR(medical,triageCard), []]; +private _index = _triageCard findIf {_x select 0 == _item}; -{ - if (_x select 0 == _newItem) exitWith { - private _info = _log select _forEachIndex; - _info set [1, (_info select 1) + 1]; - _info set [2, CBA_missionTime]; - _log set [_forEachIndex, _info]; - - _amount = _info select 1; - _inList = true; - }; -} forEach _log; - -if (!_inList) then { - _log pushBack [_newItem, 1, CBA_missionTime]; +if (_index == -1) then { + _triageCard pushBack [_item, 1, CBA_missionTime]; +} else { + _triageCard set [_index, [_item, (_triageCard select _index select 1) + 1, CBA_missionTime]]; }; -_unit setVariable [QEGVAR(medical,triageCard), _log, true]; -["ace_triageCardItemAdded", [_unit, _newItem, _amount]] call CBA_fnc_localEvent; +_unit setVariable [QEGVAR(medical,triageCard), _triageCard, true]; + +// todo: add amount of item to event args? +["ace_triageCardItemAdded", [_unit, _item]] call CBA_fnc_localEvent; diff --git a/addons/medical_treatment/functions/fnc_bandage.sqf b/addons/medical_treatment/functions/fnc_bandage.sqf new file mode 100644 index 0000000000..1a7dd4f818 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_bandage.sqf @@ -0,0 +1,25 @@ +#include "script_component.hpp" +/* + * Author: Glowbal + * Bandages open wounds on the given body part of the patient. + * + * Arguments: + * 0: Medic + * 1: Patient + * 2: Body Part + * 3: Treatment + * + * Return Value: + * None + * + * Example: + * [player, cursorObject, "Head", "FieldDressing"] call ace_medical_treatment_fnc_bandage + * + * Public: No + */ + +params ["_medic", "_patient", "_bodyPart", "_classname"]; + +[_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; diff --git a/addons/medical_treatment/functions/fnc_bandageLocal.sqf b/addons/medical_treatment/functions/fnc_bandageLocal.sqf new file mode 100644 index 0000000000..3f16f3ca76 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_bandageLocal.sqf @@ -0,0 +1,80 @@ +#include "script_component.hpp" +/* + * Author: Glowbal + * Local callback for bandaging a patient's open wounds. + * + * Arguments: + * 0: Patient + * 1: Body Part + * 2: Treatment + * + * Return Value: + * None + * + * Example: + * [player, "Head", "FieldDressing"] call ace_medical_treatment_fnc_bandageLocal + * + * Public: No + */ + +params ["_patient", "_bodyPart", "_bandage"]; +TRACE_3("bandageLocal",_patient,_bodyPart,_bandage); + +private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; +if (_partIndex < 0) exitWith {false}; + +private _openWounds = GET_OPEN_WOUNDS(_patient); +if (_openWounds isEqualTo []) exitWith {false}; + +// Figure out which injury for this bodypart is the best choice to bandage +// TODO also use up the remainder on left over injuries +private _targetWound = [_patient, _bandage, _partIndex] call FUNC(findMostEffectiveWound); +_targetWound params ["_wound", "_woundIndex", "_effectiveness"]; + +// Everything is patched up on this body part already +if (_effectiveness == -1) exitWith {}; + +// Find the impact this bandage has and reduce the amount this injury is present +private _amountOf = _wound select 2; +private _impact = _effectiveness min _amountOf; +_amountOf = _amountOf - _impact; +_wound set [2, _amountOf]; +_openWounds set [_woundIndex, _wound]; + +_patient setVariable [VAR_OPEN_WOUNDS, _openWounds, true]; + +[_patient] call EFUNC(medical_status,updateWoundBloodLoss); + +// Handle the reopening of bandaged wounds +if (_impact > 0 && {GVAR(advancedBandages) && {GVAR(woundReopening)}}) then { + [_patient, _impact, _partIndex, _woundIndex, _wound, _bandage] call FUNC(handleBandageOpening); +}; + +// Check if we fixed limping from this treatment +if ((EGVAR(medical,limping) == 1) && {_partIndex > 3} && {_amountOf <= 0} && {_patient getVariable [QEGVAR(medical,isLimping), false]}) then { + [_patient] call EFUNC(medical_engine,updateDamageEffects); +}; + +if (GVAR(clearTraumaAfterBandage)) then { + TRACE_2("clearTraumaAfterBandage - checking open wounds",_partIndex,_openWounds); + if ((_openWounds findIf { + _x params ["", "_xBodyPartN", "_xAmountOf"]; + (_partIndex ==_xBodyPartN) && {_xAmountOf > 0} + }) == -1) then { + + private _bodyPartDamage = _patient getVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]]; + _bodyPartDamage set [_partIndex, 0]; + _patient setVariable [QEGVAR(medical,bodyPartDamage), _bodyPartDamage, true]; + TRACE_2("fully healed",_partIndex,_bodyPartDamage); + + switch (_partIndex) do { + case 0: { [_patient, true, false, false, false] call EFUNC(medical_engine,updateBodyPartVisuals); }; + case 1: { [_patient, false, true, false, false] call EFUNC(medical_engine,updateBodyPartVisuals); }; + case 2; + case 3: { [_patient, false, false, true, false] call EFUNC(medical_engine,updateBodyPartVisuals); }; + default { [_patient, false, false, false, true] call EFUNC(medical_engine,updateBodyPartVisuals); }; + }; + }; +}; + +true diff --git a/addons/medical_treatment/functions/fnc_bodyCleanupLoop.sqf b/addons/medical_treatment/functions/fnc_bodyCleanupLoop.sqf index a11c9a7a25..eed0020ddf 100644 --- a/addons/medical_treatment/functions/fnc_bodyCleanupLoop.sqf +++ b/addons/medical_treatment/functions/fnc_bodyCleanupLoop.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" /* * Author: Glowbal, esteldunedain - * Loop that cleans up player bodies that were replaced by bodybags + * Handles cleaning up bodies that were replaced by body bags. * * Arguments: * None @@ -10,23 +10,23 @@ * None * * Example: - * call ace_medical_treatment_fnc_bodyCleanupLoop + * [] call ace_medical_treatment_fnc_bodyCleanupLoop * * Public: No */ { - TRACE_2("body",_x,isPlayer _x); - if ((!isNull _x) && {!isPlayer _x}) then {deleteVehicle _x}; + TRACE_2("Handling body cleanup",_x,isPlayer _x); + if (!isNull _x && {!isPlayer _x}) then {deleteVehicle _x}; } forEach GVAR(bodiesToDelete); // deleteVehicle doesn't have instant results so it won't usualy be filtered until next run GVAR(bodiesToDelete) = GVAR(bodiesToDelete) - [objNull]; -// If no more bodies remain, exit the loop +// Exit the loop if no more bodies remain if (GVAR(bodiesToDelete) isEqualTo []) exitWith { - TRACE_1("array emptied - rem PFEH",GVAR(bodiesToDelete)); + TRACE_1("Ending body cleanup loop",GVAR(bodiesToDelete)); }; -// Schedule the loop to be executed again 20 sec later -[DFUNC(bodyCleanupLoop), [], 20] call CBA_fnc_waitAndExecute; +// Schedule cleanup loop to executed again +[FUNC(litterCleanupLoop), [], BODY_CLEANUP_CHECK_DELAY] call CBA_fnc_waitAndExecute; diff --git a/addons/medical_treatment/functions/fnc_calculateBlood.sqf b/addons/medical_treatment/functions/fnc_calculateBlood.sqf deleted file mode 100644 index 074022ed29..0000000000 --- a/addons/medical_treatment/functions/fnc_calculateBlood.sqf +++ /dev/null @@ -1,29 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Zakant - * Calculate the blood lost and blood volume for a unit. Used from CPR to simulate a heart rate while in cardiac arrest. - * - * Arguments: - * 0: Unit - * - * Return Value: - * None - * - * Public: No - */ - -params["_unit"]; - -// We will just simulate blood flow for now! -private _lastTimeUpdated = _unit getVariable [QEGVAR(medical,lastTimeUpdated), CBA_missionTime]; -private _deltaT = CBA_missionTime - _lastTimeUpdated; - -private _lastTimeValuesSynced = _unit getVariable [QEGVAR(medical,lastMomentValuesSynced), 0]; -private _syncValues = (CBA_missionTime - _lastTimeValuesSynced) >= (10 + floor(random(10))); - -_unit setVariable [QEGVAR(medical,lastTimeUpdated), CBA_missionTime]; -if (_deltaT != 0) then { - private _change = ([_unit, _deltaT, _syncValues] call EFUNC(medical_status,getBloodVolumeChange)); - private _bloodVolume = 0 max (GET_BLOOD_VOLUME(_unit) + _change) min DEFAULT_BLOOD_VOLUME; - _unit setVariable [VAR_BLOOD_VOL, _bloodVolume, _syncValues]; -}; diff --git a/addons/medical_treatment/functions/fnc_canAccessMedicalEquipment.sqf b/addons/medical_treatment/functions/fnc_canAccessMedicalEquipment.sqf deleted file mode 100644 index 3544022c2b..0000000000 --- a/addons/medical_treatment/functions/fnc_canAccessMedicalEquipment.sqf +++ /dev/null @@ -1,28 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal - * Check if caller can access targets medical equipment, based upon accessLevel. - * - * Arguments: - * 0: The caller - * 1: The target - * - * Return Value: - * Can Treat - * - * Example: - * [bob, target] call ace_medical_treatment_fnc_canAccessMedicalEquipment - * - * Public: No - */ - -params ["_caller", "_target"]; - -private _accessLevel = _target getVariable [QGVAR(allowSharedEquipmentAccess), -1]; - -switch (_accessLevel) do { - case 0: { true }; - case 1: { side _target == side _caller }; - case 2: { group _target == group _caller }; - default { false }; -}; diff --git a/addons/medical_treatment/functions/fnc_canBandage.sqf b/addons/medical_treatment/functions/fnc_canBandage.sqf index 315862c753..f60836f38c 100644 --- a/addons/medical_treatment/functions/fnc_canBandage.sqf +++ b/addons/medical_treatment/functions/fnc_canBandage.sqf @@ -5,12 +5,12 @@ * Toggles between showing all or only basic bandage action for advanced setting. * * Arguments: - * 0: The medic - * 1: The patient - * 2: Body part - * 3: Treatment class name + * 0: Medic + * 1: Patient + * 2: Body Part + * 3: Treatment * - * ReturnValue: + * Return Value: * Can Bandage * * Example: @@ -19,21 +19,21 @@ * Public: No */ -params ["_medic", "_patient", "_bodypart", "_bandage"]; +params ["_medic", "_patient", "_bodyPart", "_bandage"]; // Bandage type and bandage setting XNOR to show only active actions -if ((_bandage == "BasicBandage") isEqualTo GVAR(advancedBandages)) exitWith { false }; +if ((_bandage == "BasicBandage") isEqualTo GVAR(advancedBandages)) exitWith {false}; -private _index = ALL_BODY_PARTS find toLower _bodypart; +private _index = ALL_BODY_PARTS find toLower _bodyPart; private _canBandage = false; { - _x params ["", "", "_bodyPartN", "_amountOf", "_bleeding"]; + _x params ["", "_bodyPartN", "_amountOf", "_bleeding"]; // If any single wound on the bodypart is bleeding bandaging can go ahead if (_bodyPartN == _index && {_amountOf * _bleeding > 0}) exitWith { _canBandage = true; }; -} forEach (_patient getVariable [QEGVAR(medical,openWounds), []]); +} forEach GET_OPEN_WOUNDS(_patient); _canBandage diff --git a/addons/medical_treatment/functions/fnc_canCPR.sqf b/addons/medical_treatment/functions/fnc_canCPR.sqf new file mode 100644 index 0000000000..406bccdb67 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_canCPR.sqf @@ -0,0 +1,23 @@ +#include "script_component.hpp" +/* + * Author: mharis001 + * Checks if CPR can be performed on the patient. + * + * Arguments: + * 0: Medic (not used) + * 1: Patient + * + * Return Value: + * Can CPR + * + * Example: + * [player, cursorObject] call ace_medical_treatment_fnc_canCPR + * + * Public: No + */ + +params ["", "_patient"]; + +!(_patient call EFUNC(common,isAwake)) +&& {GVAR(advancedDiagnose) || {IN_CRDC_ARRST(_patient)}} // if basic diagnose, then only show action if appropriate (they can't tell difference between uncon/ca) +&& {isNull (_patient getVariable [QEGVAR(medical,CPR_provider), objNull])} diff --git a/addons/medical_treatment/functions/fnc_canSplint.sqf b/addons/medical_treatment/functions/fnc_canSplint.sqf new file mode 100644 index 0000000000..56551ace02 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_canSplint.sqf @@ -0,0 +1,24 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Checks if a splint can be applied to the patient. + * + * Arguments: + * 0: Medic (not used) + * 1: Patient + * 2: Body Part + * + * Return Value: + * Can Splint + * + * Example: + * [player, cursorObject, "LeftLeg"] call ace_medical_treatment_fnc_canSplint + * + * Public: No + */ + +params ["", "_patient", "_bodyPart"]; + +private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; + +(GET_FRACTURES(_patient) select _partIndex) == 1 diff --git a/addons/medical_treatment/functions/fnc_canStitch.sqf b/addons/medical_treatment/functions/fnc_canStitch.sqf index d4013d97f1..ea4318874d 100644 --- a/addons/medical_treatment/functions/fnc_canStitch.sqf +++ b/addons/medical_treatment/functions/fnc_canStitch.sqf @@ -1,11 +1,11 @@ #include "script_component.hpp" /* - * Author: Katalam - * Prevents stitch actions from showing if the body is either fully stitched or has no open wounds. + * Author: Katalam, mharis001 + * Checks if the patient can be stitched. * * Arguments: - * 0: The medic - * 1: The patient + * 0: Medic (not used) + * 1: Patient * * ReturnValue: * Can Stitch @@ -18,4 +18,4 @@ params ["", "_patient"]; -!((_patient getVariable [QEGVAR(medical,bandagedWounds), []]) isEqualTo []) +!(_patient call FUNC(getStitchableWounds) isEqualTo []) diff --git a/addons/medical_treatment/functions/fnc_canTreat.sqf b/addons/medical_treatment/functions/fnc_canTreat.sqf index 26c981a02c..938e8a356d 100644 --- a/addons/medical_treatment/functions/fnc_canTreat.sqf +++ b/addons/medical_treatment/functions/fnc_canTreat.sqf @@ -1,116 +1,62 @@ #include "script_component.hpp" /* - * Author: Glowbal - * Check if the treatment action can be performed. + * Author: Glowbal, mharis001 + * Checks if the given treatment can be performed. * * Arguments: - * 0: The caller - * 1: The target - * 2: Body part - * 3: Treatment class name + * 0: Medic + * 1: Patient + * 2: Body Part + * 3: Treatment * - * ReturnValue: + * Return Value: * Can Treat * * Example: - * [player, cursorTarget, "Head", "SurgicalKit"] call ace_medical_treatment_fnc_canTreat + * [player, cursorObject, "Head", "SurgicalKit"] call ace_medical_treatment_fnc_canTreat * * Public: No */ -params ["_caller", "_target", "_bodyPart", "_className"]; +params ["_medic", "_patient", "_bodyPart", "_classname"]; -if !(_target isKindOf "CAManBase") exitWith {false}; +private _config = configFile >> QGVAR(actions) >> _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} +} && { + private _items = getArray (_config >> "items"); + _items isEqualTo [] || {[_medic, _patient, _items] call FUNC(hasItem)} +} && { + GET_FUNCTION(_condition,_config >> "condition"); -if !(isClass _config) exitWith {false}; - -// allow self treatment check -private _isSelf = _caller isEqualTo _target; -private _allowSelf = 0; - -if (_isSelf) then { - if (isNumber (_config >> "allowSelfTreatment")) then { - _allowSelf = getNumber (_config >> "allowSelfTreatment"); - } else { - if (isText (_config >> "allowSelfTreatment")) then { - _allowSelf = missionNamespace getVariable [getText (_config >> "allowSelfTreatment"), 0]; + if (_condition isEqualType {}) then { + if (_condition isEqualTo {}) exitWith { + _condition = true; }; - }; -}; - -if (_isSelf && {_allowSelf == 0}) exitWith {false}; - -private _medicRequired = 0; - -if (isNumber (_config >> "requiredMedic")) then { - _medicRequired = getNumber (_config >> "requiredMedic"); -} else { - if (isText (_config >> "requiredMedic")) then { - _medicRequired = missionNamespace getVariable [getText (_config >> "requiredMedic"), 0]; - }; -}; - -if !([_caller, _medicRequired] call FUNC(isMedic)) exitWith {false}; - -// check selection -private _allowedSelections = getArray (_config >> "allowedSelections") apply {toLower _x}; - -if !("all" in _allowedSelections || {(_bodyPart in _allowedSelections)}) exitWith {false}; - -// check item -private _items = getArray (_config >> "items"); - -if (count _items > 0 && {!([_caller, _target, _items] call FUNC(hasItems))}) exitWith {false}; - -private _condition = true; - -if (isText (_config >> "condition")) then { - _condition = getText (_config >> "condition"); - - if (_condition isEqualTo "") exitWith { - _condition = true; - }; - - if (isNil _condition) then { - _condition = compile _condition; - } else { - _condition = missionNamespace getVariable _condition; - }; - - if !(_condition isEqualType false) then { + _condition = call _condition; }; -}; -if !(_condition) exitWith {false}; - -// check allowed locations -private _locations = getArray (_config >> "treatmentLocations") apply {toLower _x}; - -if ("all" in _locations) then { - _locations = true; -} else { - private _medFacility = {([_caller] call FUNC(isInMedicalFacility)) || ([_target] call FUNC(isInMedicalFacility))}; - private _medVeh = {([_caller] call FUNC(isInMedicalVehicle)) || ([_target] call FUNC(isInMedicalVehicle))}; - - { - if (_x == "field") exitWith { _locations = true; }; - if (_x == "MedicalFacility" && _medFacility) exitWith { _locations = true; }; - if (_x == "MedicalVehicle" && _medVeh) exitWith { _locations = true; }; - if !(isNil _x) exitWith { - _locations = missionNamespace getVariable _x; - - if !(_locations isEqualType false) then { - if (_locations isEqualTo 0) exitWith { _locations = true; }; //AdvancedMedicalSettings_anywhere - if (_locations isEqualTo 1) exitWith { _locations = call _medVeh; }; //AdvancedMedicalSettings_vehicle - if (_locations isEqualTo 2) exitWith { _locations = call _medFacility; }; //AdvancedMedicalSettings_facility - if (_locations isEqualTo 3) exitWith { _locations = call _medFacility || {call _medVeh}; }; //AdvancedMedicalSettings_vehicleAndFacility - _locations = false; //Disabled - }; + _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)} }; - } forEach _locations; -}; - -_locations + 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}; + }; +} diff --git a/addons/medical_treatment/functions/fnc_canTreatCached.sqf b/addons/medical_treatment/functions/fnc_canTreatCached.sqf index 53ad59cdf4..d70f041c17 100644 --- a/addons/medical_treatment/functions/fnc_canTreatCached.sqf +++ b/addons/medical_treatment/functions/fnc_canTreatCached.sqf @@ -1,24 +1,23 @@ #include "script_component.hpp" /* * Author: Glowbal - * Cached Check if the treatment action can be performed. + * Cached check to determine if given treatment can be performed. * * Arguments: - * 0: The caller - * 1: The target - * 2: Selection name - * 3: ACE_Medical_Treatment Classname + * 0: Medic + * 1: Patient + * 2: Body Part + * 3: Treatment * * Return Value: * Can Treat * * Example: - * [bob, kevin, "selection", "classname"] call ace_medical_treatment_fnc_canTreatCached + * [player, cursorObject, "Head", "SurgicalKit"] call ace_medical_treatment_fnc_canTreatCached * * Public: No */ -params ["", "_target", "_selection", "_classname"]; +params ["", "_patient", "_bodyPart", "_classname"]; -// parameters, function, namespace, uid -[_this, DFUNC(canTreat), _target, format [QGVAR(canTreat_%1_%2), _selection, _classname], CAN_TREAT_CONDITION_CACHE_EXPIRY, QEGVAR(interact_menu,clearConditionCaches)] call EFUNC(common,cachedCall); +[_this, FUNC(canTreat), _patient, format [QGVAR(canTreat_%1_%2), _bodyPart, _classname], CAN_TREAT_CONDITION_CACHE_EXPIRY, QEGVAR(interact_menu,clearConditionCaches)] call EFUNC(common,cachedCall); diff --git a/addons/medical_treatment/functions/fnc_canTreat_holsterCheck.sqf b/addons/medical_treatment/functions/fnc_canTreat_holsterCheck.sqf new file mode 100644 index 0000000000..96f498c258 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_canTreat_holsterCheck.sqf @@ -0,0 +1,27 @@ +#include "script_component.hpp" +/* + * Author: ddm999 + * Handle holster settings [disabled, lowered, loweredExam, holster, holsterExam] + * + * Arguments: + * 0: Medic + * 1: Patient + * 2: Treatment Config + * + * Return Value: + * Can Treat + * + * Example: + * [player, cursorObject, cfg] call ace_medical_treatment_fnc_canTreat_holsterCheck + * + * Public: No + */ + +params ["_medic", "_patient", "_config"]; + +GVAR(holsterRequired) == 0 +|| {vehicle _medic != _medic} // medic is in a vehicle, so weapon is considered holstered +|| {vehicle _patient != _patient} // patient is in a vehicle, ^ +|| {(GVAR(holsterRequired) in [2,4]) && {getText (_config >> "category") == "examine"}} // if examine bypass is on +|| {currentWeapon _medic isEqualTo ""} // weapon is holstered +|| {(GVAR(holsterRequired) <= 2) && {weaponLowered _medic}} // if just lowered is allowed diff --git a/addons/medical_treatment/functions/fnc_checkBloodPressure.sqf b/addons/medical_treatment/functions/fnc_checkBloodPressure.sqf new file mode 100644 index 0000000000..b708b7e50f --- /dev/null +++ b/addons/medical_treatment/functions/fnc_checkBloodPressure.sqf @@ -0,0 +1,22 @@ +#include "script_component.hpp" +/* + * Author: Glowbal + * Checks the blood pressure of the patient. + * + * Arguments: + * 0: Medic + * 1: Patient + * 2: Body Part + * + * Return Value: + * None + * + * Example: + * [player, cursorObject, "LeftArm"] call ace_medical_treatment_fnc_checkBloodPressure + * + * Public: No + */ + +params ["_medic", "_patient", "_bodyPart"]; + +[QGVAR(checkBloodPressureLocal), [_medic, _patient, _bodyPart], _patient] call CBA_fnc_targetEvent; diff --git a/addons/medical_treatment/functions/fnc_checkBloodPressureLocal.sqf b/addons/medical_treatment/functions/fnc_checkBloodPressureLocal.sqf new file mode 100644 index 0000000000..5da7495f74 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_checkBloodPressureLocal.sqf @@ -0,0 +1,57 @@ +#include "script_component.hpp" +/* + * Author: Glowbal + * Local callback for checking the blood pressure of a patient. + * + * Arguments: + * 0: Medic + * 1: Patient + * 2: Body Part + * + * Return Value: + * None + * + * Example: + * [player, cursorObject, "LeftArm"] call ace_medical_treatment_fnc_checkBloodPressureLocal + * + * Public: No + */ + +params ["_medic", "_patient", "_bodyPart"]; + +private _bloodPressure = [0, 0]; + +if (alive _patient && {!([_patient, _bodyPart] call FUNC(hasTourniquetAppliedTo))}) then { + _bloodPressure = GET_BLOOD_PRESSURE(_patient); +}; + +private _bloodPressureOutput = LSTRING(Check_Bloodpressure_Output_6); +private _logOutput = LSTRING(Check_Bloodpressure_NoBloodpressure); + +_bloodPressure params ["_bloodPressureLow", "_bloodPressureHigh"]; + +if (_bloodPressureHigh > 20) then { + if (_medic call FUNC(isMedic)) then { + _bloodPressureOutput = LSTRING(Check_Bloodpressure_Output_1); + _logOutput = format ["%1/%2", round _bloodPressureHigh, round _bloodPressureLow]; + } else { + if (_bloodPressureHigh > 20) then { + _bloodPressureOutput = LSTRING(Check_Bloodpressure_Output_2); + _logOutput = LSTRING(Check_Bloodpressure_Low); + + if (_bloodPressureHigh > 100) then { + _bloodPressureOutput = LSTRING(Check_Bloodpressure_Output_3); + _logOutput = LSTRING(Check_Bloodpressure_Normal); + + if (_bloodPressureHigh > 160) then { + _bloodPressureOutput = LSTRING(Check_Bloodpressure_Output_4); + _logOutput = LSTRING(Check_Bloodpressure_High); + }; + }; + }; + }; +}; + +[_patient, "quick_view", LSTRING(Check_Bloodpressure_Log), [_medic call EFUNC(common,getName), _logOutput]] call FUNC(addToLog); + +[QEGVAR(common,displayTextStructured), [[_bloodPressureOutput, _patient call EFUNC(common,getName), round _bloodPressureHigh, round _bloodPressureLow], 1.75, _medic], _medic] call CBA_fnc_targetEvent; diff --git a/addons/medical_treatment/functions/fnc_checkItems.sqf b/addons/medical_treatment/functions/fnc_checkItems.sqf deleted file mode 100644 index 4c2278a408..0000000000 --- a/addons/medical_treatment/functions/fnc_checkItems.sqf +++ /dev/null @@ -1,42 +0,0 @@ -#include "script_component.hpp" -/* - * Author: KoffeinFlummi, commy2 - * Replaces vanilla items with ACE ones. - * - * Arguments: - * 0: The unit - * - * ReturnValue: - * None - * - * Public: No - */ - -if (EGVAR(medical,convertItems) == 2) exitWith {}; - -params ["_unit"]; - -private _countFirstAidKit = [_unit, "FirstAidKit"] call EFUNC(common,getCountOfItem); -_unit removeItems "FirstAidKit"; - -private _countMedikit = [_unit, "Medikit"] call EFUNC(common,getCountOfItem); -_unit removeItems "Medikit"; - -if (EGVAR(medical,convertItems) != 0) exitWith {}; - -for "_i" from 1 to _countFirstAidKit do { - _unit addItem "ACE_fieldDressing"; - _unit addItem "ACE_packingBandage"; - _unit addItem "ACE_morphine"; - _unit addItem "ACE_tourniquet"; -}; - -for "_i" from 1 to _countMedikit do { - _unit addItemToBackpack "ACE_fieldDressing"; - _unit addItemToBackpack "ACE_packingBandage"; - _unit addItemToBackpack "ACE_packingBandage"; - _unit addItemToBackpack "ACE_epinephrine"; - _unit addItemToBackpack "ACE_morphine"; - _unit addItemToBackpack "ACE_salineIV_250"; - _unit addItemToBackpack "ACE_tourniquet"; -}; diff --git a/addons/medical_treatment/functions/fnc_checkPulse.sqf b/addons/medical_treatment/functions/fnc_checkPulse.sqf new file mode 100644 index 0000000000..6c5b628fae --- /dev/null +++ b/addons/medical_treatment/functions/fnc_checkPulse.sqf @@ -0,0 +1,22 @@ +#include "script_component.hpp" +/* + * Author: Glowbal + * Checks the pulse or heart rate of the patient. + * + * Arguments: + * 0: Medic + * 1: Patient + * 2: Body Part + * + * Return Value: + * None + * + * Example: + * [player, cursorObject, "Head"] call ace_medical_treatment_fnc_checkPulse + * + * Public: No + */ + +params ["_medic", "_patient", "_bodyPart"]; + +[QGVAR(checkPulseLocal), [_medic, _patient, _bodyPart], _patient] call CBA_fnc_targetEvent; diff --git a/addons/medical_treatment/functions/fnc_checkPulseLocal.sqf b/addons/medical_treatment/functions/fnc_checkPulseLocal.sqf new file mode 100644 index 0000000000..f386fa2c89 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_checkPulseLocal.sqf @@ -0,0 +1,53 @@ +#include "script_component.hpp" +/* + * Author: Glowbal + * Local callback for checking the pulse or heart rate of a patient. + * + * Arguments: + * 0: Medic + * 1: Patient + * 2: Body Part + * + * Return Value: + * None + * + * Example: + * [player, cursorObject, "Head"] call ace_medical_treatment_fnc_checkPulseLocal + * + * Public: No + */ + +params ["_medic", "_patient", "_bodyPart"]; + +private _heartRate = 0; + +if (alive _patient && {!([_patient, _bodyPart] call FUNC(hasTourniquetAppliedTo))}) then { + _heartRate = GET_HEART_RATE(_patient); +}; + +private _heartRateOutput = LSTRING(Check_Pulse_Output_5); +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]; + } else { + _heartRateOutput = LSTRING(Check_Pulse_Output_2); + _logOutput = LSTRING(Check_Pulse_Weak); + + if (_heartRate > 60) then { + if (_heartRate > 100) then { + _heartRateOutput = LSTRING(Check_Pulse_Output_3); + _logOutput = LSTRING(Check_Pulse_Strong); + } else { + _heartRateOutput = LSTRING(Check_Pulse_Output_4); + _logOutput = LSTRING(Check_Pulse_Normal); + }; + }; + }; +}; + +[_patient, "quick_view", LSTRING(Check_Pulse_Log), [_medic call EFUNC(common,getName), _logOutput]] call FUNC(addToLog); + +[QEGVAR(common,displayTextStructured), [[_heartRateOutput, _patient call EFUNC(common,getName), round _heartRate], 1.5, _medic], _medic] call CBA_fnc_targetEvent; diff --git a/addons/medical_treatment/functions/fnc_checkResponse.sqf b/addons/medical_treatment/functions/fnc_checkResponse.sqf new file mode 100644 index 0000000000..0fe0bbd60e --- /dev/null +++ b/addons/medical_treatment/functions/fnc_checkResponse.sqf @@ -0,0 +1,24 @@ +#include "script_component.hpp" +/* + * Author: Glowbal + * Checks the response status of the patient. + * + * Arguments: + * 0: Medic + * 1: Patient + * + * Return Value: + * None + * + * Example: + * [player, cursorObject] call ace_medical_treatment_fnc_checkResponse + * + * Public: No + */ + +params ["_medic", "_patient"]; + +private _output = [LSTRING(Check_Response_Unresponsive), LSTRING(Check_Response_Responsive)] select (_patient call EFUNC(common,isAwake)); +[[_output, _patient call EFUNC(common,getName)], 2] call EFUNC(common,displayTextStructured); + +[_patient, "quick_view", _output, [[_patient, false, true] call EFUNC(common,getName)]] call FUNC(addToLog); diff --git a/addons/medical_treatment/functions/fnc_cprFailure.sqf b/addons/medical_treatment/functions/fnc_cprFailure.sqf new file mode 100644 index 0000000000..513c2e43ee --- /dev/null +++ b/addons/medical_treatment/functions/fnc_cprFailure.sqf @@ -0,0 +1,22 @@ +#include "script_component.hpp" +/* + * Author: Zakant + * Handles failure of the CPR treatment. + * + * Arguments: + * 0: Medic (not used) + * 1: Patient + * + * Return Value: + * None + * + * Example: + * [player, cursorObject] call ace_medical_treatment_fnc_cprFailure + * + * Public: No + */ + +params ["_medic", "_patient"]; +TRACE_2("cprFailure",_medic,_patient); + +_patient setVariable [QEGVAR(medical,CPR_provider), objNull, true]; diff --git a/addons/medical_treatment/functions/fnc_cprLocal.sqf b/addons/medical_treatment/functions/fnc_cprLocal.sqf new file mode 100644 index 0000000000..3d9dfd1e32 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_cprLocal.sqf @@ -0,0 +1,30 @@ +#include "script_component.hpp" +/* + * Author: Glowbal + * Local callback for finishing performing CPR on the patient. + * + * Arguments: + * 0: Medic + * 1: Patient + * + * Return Value: + * None + * + * Example: + * [player, cursorObject] call ace_medical_treatment_fnc_cprLocal + * + * Public: No + */ + +params ["_medic", "_patient"]; +TRACE_2("cprLocal",_medic,_patient); + +[_patient, "activity", LSTRING(Activity_CPR), [[_medic, false, true] call EFUNC(common,getName)]] call FUNC(addToLog); + +if ((random 1) < GVAR(cprSuccessChance)) then { + TRACE_1("CPR random success",GVAR(cprSuccessChance)); + [QEGVAR(medical,CPRSucceeded), _patient] call CBA_fnc_localEvent; +} else { + TRACE_1("CPR random fail",GVAR(cprSuccessChance)); +}; + diff --git a/addons/medical_treatment/functions/fnc_cprProgress.sqf b/addons/medical_treatment/functions/fnc_cprProgress.sqf new file mode 100644 index 0000000000..f41fefe5bf --- /dev/null +++ b/addons/medical_treatment/functions/fnc_cprProgress.sqf @@ -0,0 +1,27 @@ +#include "script_component.hpp" +/* + * Author: Zakant + * Handles the progress of the CPR treatment. + * + * Arguments: + * 0: Arguments + * 0: Medic + * 1: Patient + * + * Return Value: + * Continue CPR + * + * Example: + * [[player, cursorObject]] call ace_medical_treatment_fnc_cprProgress + * + * Public: No + */ + +params ["_args"]; +_args params ["_medic", "_patient"]; + +// Cancel CPR if patient wakes up + +!(_patient call EFUNC(common,isAwake)) +&& {(GVAR(advancedDiagnose)) || {IN_CRDC_ARRST(_patient)}} // if basic diagnose, then only show action if appropriate (they can't tell difference between uncon/ca) +&& {_medic == (_patient getVariable [QEGVAR(medical,CPR_provider), objNull])} diff --git a/addons/medical_treatment/functions/fnc_cprStart.sqf b/addons/medical_treatment/functions/fnc_cprStart.sqf new file mode 100644 index 0000000000..f49ccbb4a3 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_cprStart.sqf @@ -0,0 +1,22 @@ +#include "script_component.hpp" +/* + * Author: Zakant + * Handles starting the CPR treatment. + * + * Arguments: + * 0: Medic + * 1: Patient + * + * Return Value: + * None + * + * Example: + * [player, cursorObject] call ace_medical_treatment_fnc_cprStart + * + * Public: No + */ + +params ["_medic", "_patient"]; +TRACE_2("cprStart",_medic,_patient); + +_patient setVariable [QEGVAR(medical,CPR_provider), _medic, true]; diff --git a/addons/medical_treatment/functions/fnc_cprSuccess.sqf b/addons/medical_treatment/functions/fnc_cprSuccess.sqf new file mode 100644 index 0000000000..bd9d0c3e2b --- /dev/null +++ b/addons/medical_treatment/functions/fnc_cprSuccess.sqf @@ -0,0 +1,29 @@ +#include "script_component.hpp" +/* + * Author: Glowbal + * Handles finishing performing CPR on the patient. + * + * Arguments: + * 0: Medic + * 1: Patient + * + * Return Value: + * None + * + * Example: + * [player, cursorObject] call ace_medical_treatment_fnc_cprSuccess + * + * Public: No + */ + +params ["_medic", "_patient"]; +TRACE_2("cprSuccess",_medic,_patient); + +_patient setVariable [QEGVAR(medical,CPR_provider), objNull, true]; + +if (alive _patient && {IN_CRDC_ARRST(_patient)}) then { + TRACE_1("sending cprLocal event",_patient); + [QGVAR(cprLocal), [_medic, _patient], _patient] call CBA_fnc_targetEvent; +} else { + TRACE_1("not alive or in cardiac arrest",_patient); +}; diff --git a/addons/medical_treatment/functions/fnc_createLitter.sqf b/addons/medical_treatment/functions/fnc_createLitter.sqf new file mode 100644 index 0000000000..5aa2a5bed1 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_createLitter.sqf @@ -0,0 +1,70 @@ +#include "script_component.hpp" +/* + * Author: Glowbal, mharis001 + * Creates litter around the patient based on the treatment. + * + * Arguments: + * 0: Medic + * 1: Patient + * 2: Body Part + * 3: Treatment + * + * Return Value: + * None + * + * Example: + * [player, cursorObject, "Head", "BasicBandage"] call ace_medical_fnc_createLitter + * + * Public: No + */ + +// Exit if litter creation is disabled +if (!GVAR(allowLitterCreation)) exitWith {}; + +params ["_medic", "_patient", "_bodyPart", "_classname"]; + +// Don't create litter if medic or patient are inside a vehicle +if (vehicle _medic != _medic || {vehicle _patient != _patient}) exitWith {}; + +// Determine if treated body part is bleeding +private _index = ALL_BODY_PARTS find toLower _bodyPart; +private _isBleeding = GET_OPEN_WOUNDS(_patient) findIf { + _x params ["", "_bodyPartN", "_amountOf", "_bleeding"]; + + _bodyPartN == _index && {_amountOf * _bleeding > 0} +} != -1; + +// Get litter config for the treatment +private _litter = getArray (configFile >> QGVAR(actions) >> _classname >> "litter"); +_litter params [["_alwaysLitter", [], [[]]], ["_cleanLitter", [], [[]]], ["_bloodyLitter", [], [[]]]]; + +private _fnc_createLitter = { + params ["_litterOptions"]; + + private _position = getPosASL _patient; + + // For now, don't spawn litter over water to avoid floating litter + // todo: handle carriers over water + if (surfaceIsWater _position) exitWith {}; + + { + if (_x isEqualType []) then { + _x = selectRandom _x; + }; + + // Randomize position XY +/- 1 m + private _position = _position vectorAdd [ + random 2 - 1, + random 2 - 1, + 0 + ]; + + // Create litter on server which will also handle cleanup + [QGVAR(createLitterServer), [_x, _position, random 360]] call CBA_fnc_serverEvent; + } forEach _litterOptions; +}; + +private _conditionalLitter = [_cleanLitter, _bloodyLitter] select _isBleeding; + +[_alwaysLitter] call _fnc_createLitter; +[_conditionalLitter] call _fnc_createLitter; diff --git a/addons/medical_treatment/functions/fnc_createLitterServer.sqf b/addons/medical_treatment/functions/fnc_createLitterServer.sqf new file mode 100644 index 0000000000..5b94c5f199 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_createLitterServer.sqf @@ -0,0 +1,57 @@ +#include "script_component.hpp" +/* + * Author: Glowbal, mharis001 + * Creates a litter object and handles its cleanup. Only execute on server. + * + * Arguments: + * 0: Litter Class + * 1: Position ASL + * 2: Direction + * + * Return Value: + * None + * + * Example: + * ["Litter_1", [100, 100, 0], 90] call ace_medical_fnc_createLitterServer + * + * Public: No + */ + +params ["_litterClass", "_position", "_direction"]; + +if (isNil QGVAR(litterObjects)) then { + GVAR(litterObjects) = []; + GVAR(litterCleanup) = false; +}; + +private _model = getText (configFile >> "CfgVehicles" >> _litterClass >> "model"); +if (_model == "") exitWith {}; + +// createSimpleObject expects a path without the leading slash +if (_model select [0, 1] == "\") then { + _model = _model select [1]; +}; + +private _object = createSimpleObject [_model, [0, 0, 0]]; +_object setPosASL _position; +_object setDir _direction; + +// Set the litter object's position next frame to correct HORRIBLE spacing (fixes #1112) +[{ + params ["_object", "_position"]; + _object setPosASL _position; +}, [_object, _position]] call CBA_fnc_execNextFrame; + +// Delete oldest litter object if max count reached +if (count GVAR(litterObjects) > GVAR(maxLitterObjects)) then { + private _litterToDelete = GVAR(litterObjects) deleteAt 0; + deleteVehicle (_litterToDelete select 0); +}; + +GVAR(litterObjects) pushBack [_object, CBA_missionTime]; + +// Start cleanup loop if not already running and litter lifetime is not forever +if (!GVAR(litterCleanup) && {GVAR(litterCleanupDelay) > 0}) then { + [] call FUNC(litterCleanupLoop); + GVAR(litterCleanup) = true; +}; diff --git a/addons/medical_treatment/functions/fnc_diagnose.sqf b/addons/medical_treatment/functions/fnc_diagnose.sqf new file mode 100644 index 0000000000..531827302d --- /dev/null +++ b/addons/medical_treatment/functions/fnc_diagnose.sqf @@ -0,0 +1,49 @@ +#include "script_component.hpp" +/* + * Author: Glowbal + * Action for diagnosing in basic medical + * + * Arguments: + * 0: Medic + * 1: Patient + * + * Return Value: + * None + * + * Example: + * [player, cursorObject] call ace_medical_treatment_fnc_diagnose + * + * Public: No + */ + +params ["_medic", "_patient"]; + +private _messages = [LSTRING(diagnoseMessage), _patient call EFUNC(common,getName)]; + +if (alive _patient) then { + _messages pushBack LSTRING(diagnoseAlive); +} else { + _messages pushBack LSTRING(diagnoseDead); +}; + +private _hemorrhage = GET_HEMORRHAGE(_patient); +if (_hemorrhage > 0) then { + if (_hemorrhage > 1) then { + _messages pushBack LSTRING(lostBloodALot); + } else { + _messages pushBack LSTRING(lostBlood); + }; +} else { + _messages pushBack LSTRING(noBloodloss); +}; + +// todo: mirror pain visualization logic of medical_gui? +if (alive _patient) then { + if IS_IN_PAIN(_patient) then { + _messages pushBack LSTRING(inPain); + } else { + _messages pushBack LSTRING(noPain); + }; +}; + +[_messages, 3] call EFUNC(common,displayTextStructured); diff --git a/addons/medical_treatment/functions/fnc_findMostEffectiveWound.sqf b/addons/medical_treatment/functions/fnc_findMostEffectiveWound.sqf index a136e1be4a..a7a133c2e4 100644 --- a/addons/medical_treatment/functions/fnc_findMostEffectiveWound.sqf +++ b/addons/medical_treatment/functions/fnc_findMostEffectiveWound.sqf @@ -4,8 +4,8 @@ * Finds the wound most effective to bandage on the given bodypart of the patient for the given bandage type. * * Arguments: - * 0: The patient - * 1: Treatment class name + * 0: Patient + * 1: Treatment classname * 2: Body part index * * Return Value: @@ -29,7 +29,7 @@ if (isClass (_config >> _bandage)) then { }; // Iterate over open wounds to find the most effective target -private _openWounds = _patient getVariable [QEGVAR(medical,openWounds), []]; +private _openWounds = GET_OPEN_WOUNDS(_patient); if (_openWounds isEqualTo []) exitWith { [EMPTY_WOUND, -1, -1] }; private _wound = EMPTY_WOUND; @@ -37,15 +37,14 @@ private _woundIndex = -1; private _effectivenessFound = -1; { - _x params ["", "_classID", "_partIndexN", "_amountOf", "_bleeding", "_damage", "_category"]; + _x params ["_classID", "_partIndexN", "_amountOf", "_bleeding", "_damage"]; // Ignore wounds on other bodyparts if (_partIndexN == _partIndex) then { private _woundEffectiveness = _effectiveness; // Select the classname from the wound classname storage - private _suffix = ["Minor", "Medium", "Large"] select _category; - private _className = format ["%1%2", EGVAR(medical_damage,woundClassNames) select _classID, _suffix]; + private _className = EGVAR(medical_damage,woundClassNamesComplex) select _classID; // Get the effectiveness of the bandage on this wound type if (isClass (_config >> _className)) then { @@ -62,7 +61,7 @@ private _effectivenessFound = -1; }; // Track most effective found so far - if (_woundEffectiveness * _amountOf * _bleeding > _effectivenessFound * (_wound select 3) * (_wound select 4)) then { + if (_woundEffectiveness * _amountOf * _bleeding > _effectivenessFound * (_wound select 2) * (_wound select 3)) then { _effectivenessFound = _woundEffectiveness; _woundIndex = _forEachIndex; _wound = _x; diff --git a/addons/medical_treatment/functions/fnc_fullHeal.sqf b/addons/medical_treatment/functions/fnc_fullHeal.sqf new file mode 100644 index 0000000000..c5027e7dbe --- /dev/null +++ b/addons/medical_treatment/functions/fnc_fullHeal.sqf @@ -0,0 +1,23 @@ +#include "script_component.hpp" +/* + * Author: Glowbal + * Fully heals the patient. + * + * Arguments: + * 0: Medic + * 1: Patient + * + * Return Value: + * None + * + * Example: + * [player, cursorObject] call ace_medical_treatment_fnc_fullHeal + * + * Public: No + */ + +params ["_medic", "_patient"]; + +[_patient, "activity", LSTRING(Activity_fullHeal), [[_medic, false, true] call EFUNC(common,getName)]] call FUNC(addToLog); + +[QGVAR(fullHealLocal), _patient, _patient] call CBA_fnc_targetEvent; diff --git a/addons/medical_treatment/functions/fnc_fullHealLocal.sqf b/addons/medical_treatment/functions/fnc_fullHealLocal.sqf new file mode 100644 index 0000000000..d292394eb6 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_fullHealLocal.sqf @@ -0,0 +1,93 @@ +#include "script_component.hpp" +/* + * Author: Glowbal + * Local callback for fully healing a patient. + * + * Arguments: + * 0: Patient + * + * Return Value: + * None + * + * Example: + * [player] call ace_medical_treatment_fnc_fullHealLocal + * + * Public: No + */ + +params ["_patient"]; +TRACE_1("fullHealLocal",_patient); + +if (!alive _patient) exitWith {}; + +private _state = GET_SM_STATE(_patient); +TRACE_1("start",_state); + +// Treatment conditions would normally limit full heal to non-unconscious units +// However, this may be called externally (through Zeus) +if IN_CRDC_ARRST(_patient) then { + TRACE_1("Exiting cardiac arrest",_patient); + [QEGVAR(medical,CPRSucceeded), _patient] call CBA_fnc_localEvent; + _state = GET_SM_STATE(_patient); + TRACE_1("after CPRSucceeded",_state); +}; + +_patient setVariable [VAR_PAIN, 0, true]; +_patient setVariable [VAR_BLOOD_VOL, DEFAULT_BLOOD_VOLUME, true]; + +// Tourniquets +_patient setVariable [VAR_TOURNIQUET, DEFAULT_TOURNIQUET_VALUES, true]; +_patient setVariable [QGVAR(occludedMedications), nil, true]; + +// Wounds and Injuries +_patient setVariable [VAR_OPEN_WOUNDS, [], true]; +_patient setVariable [VAR_BANDAGED_WOUNDS, [], true]; +_patient setVariable [VAR_STITCHED_WOUNDS, [], true]; +_patient setVariable [QEGVAR(medical,isLimping), false, true]; +_patient setVariable [VAR_FRACTURES, DEFAULT_FRACTURE_VALUES, true]; + +// Update wound bleeding +[_patient] call EFUNC(medical_status,updateWoundBloodLoss); + +// Vitals +_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]; + +// IVs +_patient setVariable [QEGVAR(medical,ivBags), nil, true]; + +// Damage storage +_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); }; + 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_1("fullheal [unit %1][state %2] failed to wake up patient",_patient,_state); }; +}; + +// Generic medical admin +// _patient setVariable [VAR_CRDC_ARRST, false, true]; // this should be set by statemachine transition +// _patient setVariable [VAR_UNCON, false, true]; // this should be set by statemachine transition +_patient setVariable [VAR_HEMORRHAGE, 0, true]; +_patient setVariable [VAR_IN_PAIN, false, true]; +_patient setVariable [VAR_PAIN_SUPP, 0, true]; + +// Medication +_patient setVariable [VAR_MEDICATIONS, [], true]; + +// Reset triage card since medication is reset +_patient setVariable [QEGVAR(medical,triageCard), [], true]; + +[_patient] call EFUNC(medical_engine,updateDamageEffects); + +// Reset damage +_patient setDamage 0; + +[QEGVAR(medical,FullHeal), _patient] call CBA_fnc_localEvent; +_state = GET_SM_STATE(_patient); +TRACE_1("after FullHeal",_state); diff --git a/addons/medical_treatment/functions/fnc_getBandageTime.sqf b/addons/medical_treatment/functions/fnc_getBandageTime.sqf index 442c7ee0b4..d66a8515ae 100644 --- a/addons/medical_treatment/functions/fnc_getBandageTime.sqf +++ b/addons/medical_treatment/functions/fnc_getBandageTime.sqf @@ -4,13 +4,16 @@ * Calculates the time to bandage a wound based on it's size, the patient and the medic. * * Arguments: - * 0: The medic - * 1: The patient - * 2: Body part - * 3: Treatment class name + * 0: Medic + * 1: Patient + * 2: Body Part + * 3: Treatment * * Return Value: - * Time in seconds + * Treatment Time + * + * Example: + * [player, cursorTarget, "Head", "FieldDressing"] call ace_medical_treatment_fnc_getBandageTime * * Public: No */ @@ -18,22 +21,25 @@ params ["_medic", "_patient", "_bodypart", "_bandage"]; private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; -if (_partIndex < 0) exitWith { 0 }; +if (_partIndex < 0) exitWith { ERROR_1("invalid partIndex - %1",_this); 0 }; private _targetWound = [_patient, _bandage, _partIndex] call FUNC(findMostEffectiveWound); _targetWound params ["_wound", "_woundIndex", "_effectiveness"]; +TRACE_3("findMostEffectiveWound",_wound,_woundIndex,_effectiveness); // Everything is patched up on this body part already if (_wound isEqualTo EMPTY_WOUND) exitWith { 0 }; -_wound params ["", "", "", "_amountOf", "_bloodloss", "_damage", "_category"]; +_wound params ["_classID", "", "_amountOf", "_bloodloss", "_damage"]; +private _category = (_classID % 10); // Base bandage time is based on wound size and remaining percentage -private _bandageTime = ([ - BANDAGE_TIME_S, - BANDAGE_TIME_M, - BANDAGE_TIME_L -] select _category) * _amountOf; +private _bandageTime = [BANDAGE_TIME_S, BANDAGE_TIME_M, BANDAGE_TIME_L] select _category; + +// Scale bandage time based on amount left and effectiveness (less time if only a little wound left) +if (GVAR(advancedBandages)) then { // basicBandage will have a very high effectiveness and can be ignored + _bandageTime = _bandageTime * (linearConversion [0, _effectiveness, _amountOf, 0.666, 1, true]); +}; // Medics are more practised at applying bandages if ([_medic] call FUNC(isMedic)) then { @@ -45,5 +51,6 @@ if (_medic == _patient) then { _bandageTime = _bandageTime + BANDAGE_TIME_MOD_SELF; }; +TRACE_1("",_bandageTime); // Nobody can bandage instantly -_bandageTime max 1 +_bandageTime max 2.25 diff --git a/addons/medical_treatment/functions/fnc_getHealTime.sqf b/addons/medical_treatment/functions/fnc_getHealTime.sqf new file mode 100644 index 0000000000..e8e8c302bf --- /dev/null +++ b/addons/medical_treatment/functions/fnc_getHealTime.sqf @@ -0,0 +1,29 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Calculates the PAK treatment time based on the amount of damage to heal. + * + * Arguments: + * 0: Medic (not used) + * 1: Patient + * + * Return Value: + * Treatment Time + * + * Example: + * [player] call ace_medical_treatment_fnc_getHealTime + * + * Public: No + */ + +#define DAMAGE_SCALING_FACTOR 5 + +params ["", "_patient"]; + +private _bodyPartDamage = 0; + +{ + _bodyPartDamage = _bodyPartDamage + _x; +} forEach (_patient getVariable [QEGVAR(medical,bodyPartDamage), []]); + +10 max (((_bodyPartDamage * DAMAGE_SCALING_FACTOR) min 180) * GVAR(timeCoefficientPAK)) diff --git a/addons/medical_treatment/functions/fnc_getStitchTime.sqf b/addons/medical_treatment/functions/fnc_getStitchTime.sqf new file mode 100644 index 0000000000..9d0254605a --- /dev/null +++ b/addons/medical_treatment/functions/fnc_getStitchTime.sqf @@ -0,0 +1,21 @@ +#include "script_component.hpp" +/* + * Author: mharis001 + * Calculates the Surgical Kit treatment time based on the amount of stitchable wounds. + * + * Arguments: + * 0: Medic (not used) + * 1: Patient + * + * Return Value: + * Treatment Time + * + * Example: + * [player, cursorObject] call ace_medical_treatment_fnc_getStitchTime + * + * Public: No + */ + +params ["", "_patient"]; + +count (_patient call FUNC(getStitchableWounds)) * WOUND_STITCH_TIME diff --git a/addons/medical_treatment/functions/fnc_getStitchableWounds.sqf b/addons/medical_treatment/functions/fnc_getStitchableWounds.sqf new file mode 100644 index 0000000000..a46d878409 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_getStitchableWounds.sqf @@ -0,0 +1,33 @@ +#include "script_component.hpp" +/* + * Author: mharis001 + * Returns a list of all the stitchable wounds that the given unit has. + * A stitchable wound is a bandaged wound on a body part that does not have any bleeding wounds. + * + * Arguments: + * 0: Unit + * + * Return Value: + * Stitchable Wounds + * + * Example: + * [player] call ace_medical_treatment_fnc_getStitchableWounds + * + * Public: No + */ + +params ["_unit"]; + +private _bleedingBodyParts = GET_OPEN_WOUNDS(_unit) select { + _x params ["", "", "_amountOf", "_bleedingRate"]; + + _amountOf > 0 && {_bleedingRate > 0} +} apply { + _x select 1 +}; + +GET_BANDAGED_WOUNDS(_unit) select { + _x params ["", "_bodyPartN"]; + + !(_bodyPartN in _bleedingBodyParts) +} diff --git a/addons/medical_treatment/functions/fnc_getTriageStatus.sqf b/addons/medical_treatment/functions/fnc_getTriageStatus.sqf index de4f78a853..6db6484b8f 100644 --- a/addons/medical_treatment/functions/fnc_getTriageStatus.sqf +++ b/addons/medical_treatment/functions/fnc_getTriageStatus.sqf @@ -7,11 +7,11 @@ * 0: Unit * * Return Value: - * Triage info - * 0: Status ID - * 1: Name - * 2: Color - * 3: Text color + * Triage Info + * 0: Status ID + * 1: Name + * 2: Color + * 3: Text Color * * Example: * [player] call ace_medical_treatment_fnc_getTriageStatus diff --git a/addons/medical_treatment/functions/fnc_handleBandageOpening.sqf b/addons/medical_treatment/functions/fnc_handleBandageOpening.sqf index 1953dfce20..f2966d5f9c 100644 --- a/addons/medical_treatment/functions/fnc_handleBandageOpening.sqf +++ b/addons/medical_treatment/functions/fnc_handleBandageOpening.sqf @@ -20,12 +20,9 @@ params ["_target", "_impact", "_part", "_injuryIndex", "_injury", "_bandage"]; TRACE_6("handleBandageOpening",_target,_impact,_part,_injuryIndex,_injury,_bandage); -private _classID = _injury select 1; -private _bodyPartN = _injury select 2; -private _category = _injury select 6; -private _postfix = ["Minor", "Medium", "Large"] select _category; -private _className = format ["%1%2", EGVAR(medical_damage,woundClassNames) select _classID, _postfix]; +_injury params ["_classID", "_bodyPartN"]; +private _className = EGVAR(medical_damage,woundClassNamesComplex) select _classID; private _reopeningChance = DEFAULT_BANDAGE_REOPENING_CHANCE; private _reopeningMinDelay = DEFAULT_BANDAGE_REOPENING_MIN_DELAY; private _reopeningMaxDelay = DEFAULT_BANDAGE_REOPENING_MAX_DELAY; @@ -61,24 +58,25 @@ if (isClass (_config >> _className)) then { }; TRACE_5("configs",_bandage,_className,_reopeningChance,_reopeningMinDelay,_reopeningMaxDelay); -private _bandagedWounds = _target getVariable [QEGVAR(medical,bandagedWounds), []]; +private _bandagedWounds = GET_BANDAGED_WOUNDS(_target); private _exist = false; { - _x params ["", "_id", "_partN", "_amountOf", "", "", "_oldCategory"]; - if (_id == _classID && {_partN == _bodyPartN && {_oldCategory == _category}}) exitWith { - _x set [3, _amountOf + _impact]; - _bandagedWounds set [_forEachIndex, _x]; + _x params ["_id", "_partN", "_amountOf"]; + if (_id == _classID && {_partN == _bodyPartN}) exitWith { + _x set [2, _amountOf + _impact]; + TRACE_2("adding to existing bandagedWound",_id,_partN); _exist = true; }; } forEach _bandagedWounds; if (!_exist) then { + TRACE_2("adding new bandagedWound",_classID,_bodyPartN); private _bandagedInjury = +_injury; - _bandagedInjury set [3, _impact]; + _bandagedInjury set [2, _impact]; _bandagedWounds pushBack _bandagedInjury; }; -_target setVariable [QEGVAR(medical,bandagedWounds), _bandagedWounds, true]; +_target setVariable [VAR_BANDAGED_WOUNDS, _bandagedWounds, true]; // _reopeningChance = 1; // _reopeningMinDelay = 5; @@ -93,32 +91,37 @@ if (random 1 <= _reopeningChance) then { params ["_target", "_impact", "_part", "_injuryIndex", "_injury"]; TRACE_5("reopen delay finished",_target,_impact,_part,_injuryIndex,_injury); - private _openWounds = _target getVariable [QEGVAR(medical,openWounds), []]; + private _openWounds = GET_OPEN_WOUNDS(_target); if (count _openWounds - 1 < _injuryIndex) exitWith { TRACE_2("index bounds",_injuryIndex,count _openWounds); }; - _injury params ["", "_classID", "_bodyPartN", "", "", "", "_category"]; + _injury params ["_classID", "_bodyPartN"]; private _selectedInjury = _openWounds select _injuryIndex; - if (_selectedInjury select 1 == _classID && {_selectedInjury select 2 == _bodyPartN}) then { // matching the IDs - private _bandagedWounds = _target getVariable [QEGVAR(medical,bandagedWounds), []]; + _selectedInjury params ["_selClassID", "_selBodyPart", "_selAmmount"]; + if ((_selClassID == _classID) && {_selBodyPart == _bodyPartN}) then { // matching the IDs + private _bandagedWounds = GET_BANDAGED_WOUNDS(_target); private _exist = false; { - _x params ["", "_id", "_partN", "_amountOf", "", "", "_oldCategory"]; - if (_id == _classID && {_partN == _bodyPartN && {_oldCategory == _category}}) exitWith { - _x set [3, 0 max (_amountOf - _impact)]; - _bandagedWounds set [_forEachIndex, _x]; + _x params ["_id", "_partN", "_amountOf"]; + if ((_id == _classID) && {_partN == _bodyPartN}) exitWith { + TRACE_2("bandagedWound exists",_id,_classID); + _x set [2, 0 max (_amountOf - _impact)]; _exist = true; }; } forEach _bandagedWounds; if (_exist) then { TRACE_2("Reopening Wound",_bandagedWounds,_openWounds); - _selectedInjury set [3, (_selectedInjury select 3) + _impact]; - _openWounds set [_injuryIndex, _selectedInjury]; - _target setVariable [QEGVAR(medical,bandagedWounds), _bandagedWounds, true]; - _target setVariable [QEGVAR(medical,openWounds), _openWounds, true]; + _selectedInjury set [2, _selAmmount + _impact]; + _target setVariable [VAR_BANDAGED_WOUNDS, _bandagedWounds, true]; + _target setVariable [VAR_OPEN_WOUNDS, _openWounds, true]; [_target] call EFUNC(medical_status,updateWoundBloodLoss); + + // Check if we gained limping from this wound re-opening + if ((EGVAR(medical,limping) == 1) && {_bodyPartN > 3}) then { + [_target] call EFUNC(medical_engine,updateDamageEffects); + }; }; } else { TRACE_3("no match",_selectedInjury,_classID,_bodyPartN); diff --git a/addons/medical_treatment/functions/fnc_hasItem.sqf b/addons/medical_treatment/functions/fnc_hasItem.sqf index f6e07b576e..564e7c4be2 100644 --- a/addons/medical_treatment/functions/fnc_hasItem.sqf +++ b/addons/medical_treatment/functions/fnc_hasItem.sqf @@ -1,44 +1,31 @@ #include "script_component.hpp" /* - * Author: Glowbal - * Check if the item is present between the patient and the medic + * Author: Glowbal, mharis001 + * Checks if one of the given items are present between the medic and patient. + * Does not respect the priority defined by the allowSharedEquipment setting. + * Will check medic first and then patient if shared equipment is allowed. * * Arguments: * 0: Medic * 1: Patient - * 2: Item + * 2: Items * * Return Value: - * Has the items + * Has Item * * Example: - * [bob, patient, "bandage"] call ace_medical_treatment_fnc_hasItem + * [player, cursorObject, ["ACE_fieldDressing"]] call ace_medical_treatment_fnc_hasItems * * Public: No */ -params ["_medic", "_patient", "_item"]; +params ["_medic", "_patient", "_items"]; -if (isNil QEGVAR(medical,setting_allowSharedEquipment)) then { - EGVAR(medical,setting_allowSharedEquipment) = true; +private _fnc_checkItems = { + params ["_unit"]; + + private _unitItems = _unit call EFUNC(common,uniqueItems); + _items findIf {_x in _unitItems} != -1 }; -if (EGVAR(medical,setting_allowSharedEquipment) && {[_patient, _item] call EFUNC(common,hasItem)}) exitWith { - true -}; - -if ([_medic, _item] call EFUNC(common,hasItem)) exitWith { - true -}; - -private _hasItem = false; - -if (vehicle _medic != _medic && {vehicle _medic call FUNC(isMedicalVehicle)}) then { - { - if ([_medic, _x] call FUNC(canAccessMedicalEquipment) && {[_x, _item] call EFUNC(common,hasItem)}) exitWith { - _hasItem = true; - }; - } forEach crew vehicle _medic; -}; - -_hasItem +_medic call _fnc_checkItems || {GVAR(allowSharedEquipment) != 2 && {_patient call _fnc_checkItems}} diff --git a/addons/medical_treatment/functions/fnc_hasItems.sqf b/addons/medical_treatment/functions/fnc_hasItems.sqf deleted file mode 100644 index c55ad47e34..0000000000 --- a/addons/medical_treatment/functions/fnc_hasItems.sqf +++ /dev/null @@ -1,36 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal - * Check if all items are present between the patient and the medic. - * - * Arguments: - * 0: Medic - * 1: Patient - * 2: Items > - * - * Return Value: - * Has the items - * - * Example: - * [bob, patient, ["bandage", "morphine"]] call ace_medical_treatment_fnc_hasItems - * - * Public: No - */ - -params ["_medic", "_patient", "_items"]; - -private _return = true; - -{ - // handle a one of type use item - if (_x isEqualType [] && {{[_medic, _patient, _x] call FUNC(hasItem)} count _x == 0}) exitWith { - _return = false; - }; - - // handle required item - if (_x isEqualType "" && {!([_medic, _patient, _x] call FUNC(hasItem))}) exitWith { - _return = false; - }; -} forEach _items; - -_return diff --git a/addons/medical_treatment/functions/fnc_hasTourniquetAppliedTo.sqf b/addons/medical_treatment/functions/fnc_hasTourniquetAppliedTo.sqf index d3f573cb55..c8d2aa8e7b 100644 --- a/addons/medical_treatment/functions/fnc_hasTourniquetAppliedTo.sqf +++ b/addons/medical_treatment/functions/fnc_hasTourniquetAppliedTo.sqf @@ -1,14 +1,14 @@ #include "script_component.hpp" /* * Author: Glowbal - * Check if unit has a tourniquet applied to the specified bodypart + * Checks if the unit has a tourniquet applied on the specified body part. * * Arguments: - * 0: The Unit + * 0: Unit * 1: Body Part * * Return Value: - * Has tourniquet applied + * Has Tourniquet Been Applied * * Example: * [player, "leftleg"] call ace_medical_treatment_fnc_hasTourniquetAppliedTo @@ -16,8 +16,8 @@ * Public: No */ -params ["_target", "_bodyPart"]; +params ["_unit", "_bodyPart"]; private _index = ALL_BODY_PARTS find toLower _bodyPart; -_index >= 0 && {HAS_TOURNIQUET_APPLIED_ON(_target,_index)} +_index >= 0 && {HAS_TOURNIQUET_APPLIED_ON(_unit,_index)} diff --git a/addons/medical_treatment/functions/fnc_healTime.sqf b/addons/medical_treatment/functions/fnc_healTime.sqf deleted file mode 100644 index 0dcb1f74d2..0000000000 --- a/addons/medical_treatment/functions/fnc_healTime.sqf +++ /dev/null @@ -1,32 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Ruthberg - * Calculates the personal aid kit treatment time based on amount of damage to heal - * - * Arguments: - * unit - * - * Return Value: - * treatment time - * - * Example: - * [_target] call ace_medical_treatment_fnc_healTime - * - * Public: No - */ - -params ["_unit"]; - -private _totalDamage = 0; -private _treatTime = 0; - -{ - _totalDamage = _totalDamage + _x; -} forEach (_unit getVariable [QEGVAR(medical,bodyPartDamage), []]); - -if (EGVAR(medical,PAKTime) > 0) then { - _treatTime = EGVAR(medical,PAKTime); -} else { - _treatTime = 10 max (_totalDamage * 5) min 180; -}; -_treatTime diff --git a/addons/medical_treatment/functions/fnc_isInMedicalFacility.sqf b/addons/medical_treatment/functions/fnc_isInMedicalFacility.sqf index a9b01345b8..fe144ea78a 100644 --- a/addons/medical_treatment/functions/fnc_isInMedicalFacility.sqf +++ b/addons/medical_treatment/functions/fnc_isInMedicalFacility.sqf @@ -1,13 +1,13 @@ #include "script_component.hpp" /* - * Author: Glowbal - * Checks if a unit is in a designated medical facility + * Author: Glowbal, mharis001 + * Checks if the unit is in a medical facility. * * Arguments: - * 0: The Unit + * 0: Unit * * Return Value: - * Is in medical facility + * In Medical Facility * * Example: * [player] call ace_medical_treatment_fnc_isInMedicalFacility @@ -15,49 +15,13 @@ * Public: No */ +#define CHECK_OBJECTS(var) ((var) findIf {typeOf _x in GVAR(facilityClasses) || {_x getVariable [QEGVAR(medical,isMedicalFacility), false]}} != -1) + params ["_unit"]; -//Cache the results as this function could be called rapidly -(_unit getVariable [QGVAR(cacheInFacility), [-9, false]]) params ["_expireTime", "_lastResult"]; -if (CBA_missionTime < _expireTime) exitWith {_lastResult}; - -private _eyePos = eyePos _unit; -private _isInBuilding = false; - -private _medicalFacility = - [ - "TK_GUE_WarfareBFieldhHospital_Base_EP1", - "TK_GUE_WarfareBFieldhHospital_EP1", - "TK_WarfareBFieldhHospital_Base_EP1", - "TK_WarfareBFieldhHospital_EP1", - "US_WarfareBFieldhHospital_Base_EP1", - "US_WarfareBFieldhHospital_EP1", - "MASH_EP1", - "MASH", - "Land_A_Hospital", - "CDF_WarfareBFieldhHospital", - "GUE_WarfareBFieldhHospital", - "INS_WarfareBFieldhHospital", - "RU_WarfareBFieldhHospital", - "USMC_WarfareBFieldhHospital" - ]; - -private _objects = (lineIntersectsWith [_unit modelToWorldVisual [0, 0, (_eyePos select 2)], _unit modelToWorldVisual [0, 0, (_eyePos select 2) +10], _unit]); -{ - if (((typeOf _x) in _medicalFacility) || {_x getVariable [QEGVAR(medical,isMedicalFacility),false]}) exitWith { - _isInBuilding = true; - }; -} forEach _objects; - -if (!_isInBuilding) then { - _objects = _unit nearObjects 7.5; - { - if (((typeOf _x) in _medicalFacility) || {_x getVariable [QEGVAR(medical,isMedicalFacility),false]}) exitWith { - _isInBuilding = true; - }; - } forEach _objects; +private _fnc_check = { + private _position = _unit modelToWorldVisual [0, 0, eyePos _unit select 2]; + CHECK_OBJECTS(ARR_5(lineIntersectsWith [_position, _position vectorAdd [0, 0, 10], _unit])) || {CHECK_OBJECTS(_unit nearObjects 7.5)} }; -_unit setVariable [QGVAR(cacheInFacility), [CBA_missionTime + IN_MEDICAL_FACILITY_CACHE_EXPIRY, _isInBuilding]]; - -_isInBuilding; +[[], _fnc_check, _unit, QGVAR(inMedicalFacilityCache), IN_MEDICAL_FACILITY_CACHE_EXPIRY] call EFUNC(common,cachedCall); diff --git a/addons/medical_treatment/functions/fnc_isInMedicalVehicle.sqf b/addons/medical_treatment/functions/fnc_isInMedicalVehicle.sqf index 6c4d895492..2f76f04f99 100644 --- a/addons/medical_treatment/functions/fnc_isInMedicalVehicle.sqf +++ b/addons/medical_treatment/functions/fnc_isInMedicalVehicle.sqf @@ -1,13 +1,13 @@ #include "script_component.hpp" /* * Author: KoffeinFlummi - * Checks if a unit is in a medical vehicle. + * Checks if the unit is in a medical vehicle. * * Arguments: - * 0: unit to be checked + * 0: Unit * * Return Value: - * Is unit in medical vehicle? + * In Medical Vehicle * * Example: * [player] call ace_medical_treatment_fnc_isInMedicalVehicle @@ -19,7 +19,4 @@ params ["_unit"]; private _vehicle = vehicle _unit; -if (_unit == _vehicle) exitWith {false}; -if (_unit in [driver _vehicle, gunner _vehicle, commander _vehicle]) exitWith {false}; - -[_vehicle] call FUNC(isMedicalVehicle); +_unit != _vehicle && {!(_unit in [driver _vehicle, gunner _vehicle, commander _vehicle])} && {[_vehicle] call FUNC(isMedicalVehicle)} diff --git a/addons/medical_treatment/functions/fnc_isMedic.sqf b/addons/medical_treatment/functions/fnc_isMedic.sqf index 65bbdcc853..d109ad2452 100644 --- a/addons/medical_treatment/functions/fnc_isMedic.sqf +++ b/addons/medical_treatment/functions/fnc_isMedic.sqf @@ -1,14 +1,15 @@ #include "script_component.hpp" /* * Author: Glowbal, KoffeinFlummi - * Check if a unit is any medical class + * Checks if the unit is a medic of the given level. + * Medic Levels: 0 - None, 1 - Medic, 2 - Doctor * * Arguments: - * 0: The Unit - * 1: Class (default: 1) + * 0: Unit + * 1: Medic Level (default: 1) * * Return Value: - * Is in of medic class + * Is Medic * * Example: * [player] call ace_medical_treatment_fnc_isMedic @@ -18,13 +19,13 @@ params ["_unit", ["_medicN", 1]]; -private _class = _unit getVariable [QEGVAR(medical,medicClass), [0, 1] select (_unit getUnitTrait "medic")]; +private _class = _unit getVariable [QEGVAR(medical,medicClass), parseNumber (_unit getUnitTrait "medic")]; if (_class >= _medicN) exitWith {true}; -if (!EGVAR(medical,increaseTrainingInLocations)) exitWith {false}; +if (!GVAR(locationsBoostTraining)) exitWith {false}; -if (([_unit] call FUNC(isInMedicalVehicle)) || {[_unit] call FUNC(isInMedicalFacility)}) then { - _class = _class + 1; //boost by one: untrained becomes medic, medic becomes doctor +if (IN_MED_VEHICLE(_unit) || {IN_MED_FACILITY(_unit)}) then { + _class = _class + 1; // Boost medical training by one: untrained becomes medic, medic becomes doctor }; _class >= _medicN diff --git a/addons/medical_treatment/functions/fnc_isMedicalVehicle.sqf b/addons/medical_treatment/functions/fnc_isMedicalVehicle.sqf index d109a14e87..4b06ffdb55 100644 --- a/addons/medical_treatment/functions/fnc_isMedicalVehicle.sqf +++ b/addons/medical_treatment/functions/fnc_isMedicalVehicle.sqf @@ -1,13 +1,13 @@ #include "script_component.hpp" /* * Author: Glowbal - * Check if vehicle is a medical vehicle + * Checks if the vehicle is a medical vehicle. * * Arguments: - * 0: The Vehicle + * 0: Vehicle * * Return Value: - * Is in of medic class + * Is Medical Vehicle * * Example: * [cursorObject] call ace_medical_treatment_fnc_isMedicalVehicle @@ -17,4 +17,4 @@ params ["_vehicle"]; -(_vehicle getVariable [QEGVAR(medical,medicClass), getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> "attendant")]) > 0 +_vehicle getVariable [QEGVAR(medical,isMedicalVehicle), getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> "attendant") > 0] diff --git a/addons/medical_treatment/functions/fnc_ivBag.sqf b/addons/medical_treatment/functions/fnc_ivBag.sqf new file mode 100644 index 0000000000..bfc149564e --- /dev/null +++ b/addons/medical_treatment/functions/fnc_ivBag.sqf @@ -0,0 +1,28 @@ +#include "script_component.hpp" +/* + * Author: Glowbal, mharis001 + * Administers an IV bag treatment to the patient. + * + * Arguments: + * 0: Medic + * 1: Patient + * 2: Body Part + * 3: Treatment + * 4: Item User (not used) + * 5: Used Item + * + * Return Value: + * None + * + * Example: + * [player, cursorObject, "RightArm", "BloodIV", objNull, "ACE_bloodIV"] call ace_medical_treatment_fnc_ivBag + * + * Public: No + */ + +params ["_medic", "_patient", "_bodyPart", "_classname", "", "_usedItem"]; + +[_patient, _usedItem] call FUNC(addToTriageCard); +[_patient, "activity", LSTRING(Activity_gaveIV), [[_medic, false, true] call EFUNC(common,getName)]] call FUNC(addToLog); + +[QGVAR(ivBagLocal), [_patient, _bodyPart, _classname], _patient] call CBA_fnc_targetEvent; diff --git a/addons/medical_treatment/functions/fnc_ivBagLocal.sqf b/addons/medical_treatment/functions/fnc_ivBagLocal.sqf new file mode 100644 index 0000000000..f2640fb0bf --- /dev/null +++ b/addons/medical_treatment/functions/fnc_ivBagLocal.sqf @@ -0,0 +1,38 @@ +#include "script_component.hpp" +/* + * Author: Glowbal, mharis001 + * Local callback for administering an IV bag to a patient. + * + * Arguments: + * 0: Patient + * 1: Body Part + * 2: Treatment + * + * Return Value: + * None + * + * Example: + * [player, "RightArm", "BloodIV"] call ace_medical_treatment_fnc_ivBagLocal + * + * Public: No + */ + +params ["_patient", "_bodyPart", "_classname"]; + +// Exit if patient has max blood volume +private _bloodVolume = GET_BLOOD_VOLUME(_patient); +if (_bloodVolume >= DEFAULT_BLOOD_VOLUME) exitWith {}; + +private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; + +// Get attributes for the used IV +private _defaultConfig = configFile >> QUOTE(ADDON) >> "IV"; +private _ivConfig = _defaultConfig >> _classname; + +private _volume = GET_NUMBER(_ivConfig >> "volume",getNumber (_defaultConfig >> "volume")); +private _type = GET_STRING(_ivConfig >> "type",getText (_defaultConfig >> "type")); + +// Add IV bag to patient's ivBags array +private _ivBags = _patient getVariable [QEGVAR(medical,ivBags), []]; +_ivBags pushBack [_volume, _type, _partIndex]; +_patient setVariable [QEGVAR(medical,ivBags), _ivBags, true]; diff --git a/addons/medical_treatment/functions/fnc_litterCleanupLoop.sqf b/addons/medical_treatment/functions/fnc_litterCleanupLoop.sqf index 20b2cc20ec..1039edb4c6 100644 --- a/addons/medical_treatment/functions/fnc_litterCleanupLoop.sqf +++ b/addons/medical_treatment/functions/fnc_litterCleanupLoop.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" /* - * Author: Glowbal, esteldunedain - * Loop that cleans up litter + * Author: Glowbal, esteldunedain, mharis001 + * Handles cleaning up litter objects that have reached the end of their lifetime. * * Arguments: * None @@ -10,31 +10,28 @@ * None * * Example: - * call ace_medical_treatment_fnc_litterCleanupLoop + * [] call ace_medical_treatment_fnc_litterCleanupLoop * * Public: No */ { - _x params ["_time", "_objects"]; + _x params ["_object", "_timeCreated"]; - // Older elements are always at the begining of the array - if (CBA_missionTime - _time < GVAR(litterCleanUpDelay)) exitWith {}; + // Litter array has older objects at the beginning + // Can exit on first element that still has lifetime remaining + if (CBA_missionTime - _timeCreated < GVAR(litterCleanupDelay)) exitWith {}; - TRACE_2("deleting",_time,_objects); - { - deleteVehicle _x; - } forEach _objects; + deleteVehicle _object; + GVAR(litterObjects) set [_forEachIndex, objNull]; +} forEach GVAR(litterObjects); - GVAR(allCreatedLitter) set [_forEachIndex, objNull]; -} forEach GVAR(allCreatedLitter); +GVAR(litterObjects) = GVAR(litterObjects) - [objNull]; -GVAR(allCreatedLitter) = GVAR(allCreatedLitter) - [objNull]; - -// If no more litter remain, exit the loop -if (GVAR(allCreatedLitter) isEqualTo []) exitWith { - GVAR(litterPFHRunning) = false; +// Exit the loop if no litter objects left +if (GVAR(litterObjects) isEqualTo []) exitWith { + GVAR(litterCleanup) = false; }; -// Schedule the loop to be executed again 30 sec later -[FUNC(litterCleanupLoop), [], 30] call CBA_fnc_waitAndExecute; +// Schedule cleanup loop to executed again +[FUNC(litterCleanupLoop), [], LITTER_CLEANUP_CHECK_DELAY] call CBA_fnc_waitAndExecute; diff --git a/addons/medical_treatment/functions/fnc_litterCreate.sqf b/addons/medical_treatment/functions/fnc_litterCreate.sqf deleted file mode 100644 index 1f48a56a8b..0000000000 --- a/addons/medical_treatment/functions/fnc_litterCreate.sqf +++ /dev/null @@ -1,98 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal - * Spawns litter for the treatment action on the ground around the target - * - * Arguments: - * 0: The Caller - * 1: The target - * 2: The treatment Selection Name - * 3: The treatment classname - * 4: ? - * 5: Users of Items - * 6: Blood Loss on selection (previously called _previousDamage) - * - * Return Value: - * None - * - * Public: No - */ - -#define MIN_ENTRIES_LITTER_CONFIG 3 - -params ["_caller", "_target", "_selectionName", "_className", "", "_usersOfItems", "_bloodLossOnSelection"]; -TRACE_6("params",_caller,_target,_selectionName,_className,_usersOfItems,_bloodLossOnSelection); - -// Ensures comptibilty with other possible medical treatment configs -private _previousDamage = _bloodLossOnSelection; - -// Exit if litter is disabled by setting -if !(EGVAR(medical,allowLitterCreation)) exitWith {}; - -// Don't create litter if medic or patient are inside a vehicle -if (vehicle _caller != _caller || {vehicle _target != _target}) exitWith {}; - -private _config = configFile >> QGVAR(Actions) >> _className; -if !(isClass _config) exitWith {TRACE_1("No action config",_className);}; - -if !(isArray (_config >> "litter")) exitWith {TRACE_1("No litter config",_className);}; -private _litter = getArray (_config >> "litter"); - -private _createLitter = { - params ["_unit", "_litterClass"]; - - private _position = getPosASL _unit; - - // @TODO: handle carriers over water - // For now, don't spawn litter if we are over water to avoid floating litter - if (surfaceIsWater _position) exitWith {false}; - - _position = _position vectorAdd [ - random 2 - 1, - random 2 - 1, - 0 - ]; - - private _direction = random 360; - - // Create the litter, and timeout the event based on the cleanup delay - // The cleanup delay for events in MP is handled by the server side - TRACE_3("Creating Litter on server",_litterClass,_position,_direction); - [QGVAR(createLitterServer), [_litterClass, _position, _direction]] call CBA_fnc_serverEvent; - - true -}; - -{ - if (count _x < MIN_ENTRIES_LITTER_CONFIG) then { - WARNING_1("Wrong litter array: %1",_x); - } else { - _x params [ - ["_selection", "", [""]], - ["_litterCondition", "", [""]], - ["_litterOptions", [], [[]]] - ]; - - if (toLower _selection in [toLower _selectionName, "all"]) then { - if (_litterCondition isEqualTo "") then { - _litterCondition = {true}; - } else { - _litterCondition = compile _litterCondition; - }; - - // existing configs seem to use carried over magic variables. we pass them as arguments (_this) anyway - if !([_caller, _target, _selectionName, _className, _usersOfItems, _bloodLossOnSelection] call _litterCondition) exitWith {}; - - // Loop through through the litter options and place the litter - { - if (_x isEqualType "") then { - [_target, _x] call _createLitter; - }; - - if (_x isEqualType [] && {count _x > 0}) then { - [_target, selectRandom _x] call _createLitter; - }; - } foreach _litterOptions; - }; - }; -} foreach _litter; diff --git a/addons/medical_treatment/functions/fnc_litterHandleCreate.sqf b/addons/medical_treatment/functions/fnc_litterHandleCreate.sqf deleted file mode 100644 index 10cbc1f580..0000000000 --- a/addons/medical_treatment/functions/fnc_litterHandleCreate.sqf +++ /dev/null @@ -1,68 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal - * handle Litter Create - * - * Arguments: - * 0: Litter Class - * 1: Position - * 2: Unit - * - * Return Value: - * None - * - * Example: - * ["litter", [2, 5, 6], bob] call ace_medical_treatment_fnc_handleCreateLitter - * - * Public: No - */ - -params ["_litterClass", "_position", "_direction"]; -TRACE_3("params",_litterClass,_position,_direction); - -//IGNORE_PRIVATE_WARNING ["_values"]; - -if (isNil QGVAR(allCreatedLitter)) then { - GVAR(allCreatedLitter) = []; - GVAR(litterPFHRunning) = false; -}; - -private _model = getText (configFile >> "CfgVehicles" >> _litterClass >> "model"); -if (_model == "") exitWith {TRACE_2("no model",_litterClass,_model)}; - -// createSimpleObject expects a path without the leading slash -if (_model select [0,1] == "\") then { - _model = _model select [1]; -}; - -private _litterObject = createSimpleObject [_model, [0,0,0]]; -TRACE_2("created",_litterClass,_litterObject); - -_litterObject setDir _direction; -_litterObject setPosASL _position; - -// Move the litter next frame to get rid of HORRIBLE spacing, fixes #1112 -[{ - params ["_object", "_position"]; - - _object setPosASL _position; -}, [_litterObject, _position]] call CBA_fnc_execNextFrame; - -private _maxLitterCount = getArray (configFile >> "ACE_Settings" >> QEGVAR(medical,litterSimulationDetail) >> "_values") select EGVAR(medical,litterSimulationDetail); - -if (count GVAR(allCreatedLitter) > _maxLitterCount) then { - // gank the first litter object, and spawn ours. - private _oldLitter = GVAR(allCreatedLitter) deleteAt 0; - - { - deleteVehicle _x; - } forEach (_oldLitter select 1); -}; - -GVAR(allCreatedLitter) pushBack [CBA_missionTime, [_litterObject]]; - -if (!GVAR(litterPFHRunning) && {GVAR(litterCleanUpDelay) > 0}) then { - // Start the litter cleanup loop - GVAR(litterPFHRunning) = true; - call FUNC(litterCleanupLoop); -}; diff --git a/addons/medical_treatment/functions/fnc_loadUnit.sqf b/addons/medical_treatment/functions/fnc_loadUnit.sqf new file mode 100644 index 0000000000..74e66d517b --- /dev/null +++ b/addons/medical_treatment/functions/fnc_loadUnit.sqf @@ -0,0 +1,52 @@ +#include "script_component.hpp" +/* + * Author: Glowbal + * Loads an unconscious or dead patient in the given or nearest vehicle. + * + * Arguments: + * 0: Medic + * 1: Patient + * 2: Vehicle (default: objNull) + * + * Return Value: + * None + * + * Example: + * [player, cursorObject] call ace_medical_treatment_fnc_loadUnit + * + * Public: No + */ + +params ["_medic", "_patient", ["_vehicle", objNull]]; +TRACE_3("loadUnit",_medic,_patient,_vehicle); + +if (_patient call EFUNC(common,isAwake)) exitWith { + [[LSTRING(CanNotLoad), _patient call EFUNC(common,getName)]] call EFUNC(common,displayTextStructured); +}; + +if (_patient call EFUNC(medical_status,isBeingCarried)) then { + [_medic, _patient] call EFUNC(dragging,dropObject_carry); +}; + +if (_patient call EFUNC(medical_status,isBeingDragged)) then { + [_medic, _patient] call EFUNC(dragging,dropObject); +}; + +private _vehicle = [_medic, _patient, _vehicle] call EFUNC(common,loadPerson); + +if (isNull _vehicle) exitWith { TRACE_1("no vehicle found",_vehicle); }; + +[{ + params ["_unit", "_vehicle"]; + (alive _unit) && {alive _vehicle} && {(vehicle _unit) == _vehicle} +}, { + params ["_unit", "_vehicle"]; + TRACE_2("success",_unit,_vehicle); + private _patientName = [_unit, false, true] call EFUNC(common,getName); + private _vehicleName = getText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "displayName"); + [[LSTRING(LoadedInto), _patientName, _vehicleName], 3] call EFUNC(common,displayTextStructured); +}, [_patient, _vehicle], 3, { + params ["_unit", "_emptyPos"]; + WARNING_3("loadPerson failed to load %1[local %2] -> %3 ",_unit,local _unit,_vehicle); +}] call CBA_fnc_waitUntilAndExecute; + diff --git a/addons/medical_treatment/functions/fnc_medication.sqf b/addons/medical_treatment/functions/fnc_medication.sqf new file mode 100644 index 0000000000..6def70b212 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_medication.sqf @@ -0,0 +1,28 @@ +#include "script_component.hpp" +/* + * Author: Glowbal, mharis001 + * Administers medication to the patient on the given body bodypart. + * + * Arguments: + * 0: Medic + * 1: Patient + * 2: Body Part + * 3: Treatment + * 4: Item User (not used) + * 5: Used Item + * + * Return Value: + * None + * + * Example: + * [player, cursorObject, "RightArm", "Morphine", objNull, "ACE_morphine"] call ace_medical_treatment_fnc_medication + * + * Public: No + */ + +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); + +[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 new file mode 100644 index 0000000000..bb14e14b5b --- /dev/null +++ b/addons/medical_treatment/functions/fnc_medicationLocal.sqf @@ -0,0 +1,78 @@ +#include "script_component.hpp" +/* + * Author: Glowbal, mharis001 + * Local callback for administering medication to a patient. + * + * Arguments: + * 0: Patient + * 1: Body Part + * 2: Treatment + * + * Return Value: + * None + * + * Example: + * [player, "RightArm", "Morphine"] call ace_medical_treatment_fnc_medicationLocal + * + * Public: No + */ + +// todo: move this macro to script_macros_medical.hpp? +#define MORPHINE_PAIN_SUPPRESSION 0.6 + +params ["_patient", "_bodyPart", "_classname"]; +TRACE_3("medicationLocal",_patient,_bodyPart,_classname); + +// Medication has no effects on dead units +if (!alive _patient) exitWith {}; + +// Exit with basic medication handling if advanced medication not enabled +if (!GVAR(advancedMedication)) exitWith { + switch (_classname) do { + case "Morphine": { + private _painSuppress = GET_PAIN_SUPPRESS(_patient); + _patient setVariable [VAR_PAIN_SUPP, (_painSuppress + MORPHINE_PAIN_SUPPRESSION) min 1, true]; + }; + case "Epinephrine": { + [QEGVAR(medical,WakeUp), _patient] call CBA_fnc_localEvent; + }; + }; +}; +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; + +if (HAS_TOURNIQUET_APPLIED_ON(_patient,_partIndex)) exitWith { + TRACE_1("unit has tourniquets blocking blood flow on injection site",_tourniquets); + private _occludedMedications = _patient getVariable [QEGVAR(medical,occludedMedications), []]; + _occludedMedications pushBack [_partIndex, _classname]; + _patient setVariable [QEGVAR(medical,occludedMedications), _occludedMedications, true]; +}; + +// Get adjustment attributes for used medication +private _defaultConfig = configFile >> QUOTE(ADDON) >> "Medication"; +private _medicationConfig = _defaultConfig >> _classname; + +private _painReduce = GET_NUMBER(_medicationConfig >> "painReduce",getNumber (_defaultConfig >> "painReduce")); +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 _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")); +private _hrIncreaseHigh = GET_ARRAY(_medicationConfig >> "hrIncreaseHigh",getArray (_defaultConfig >> "hrIncreaseHigh")); +private _incompatibleMedication = GET_ARRAY(_medicationConfig >> "incompatibleMedication",getArray (_defaultConfig >> "incompatibleMedication")); + +private _heartRate = GET_HEART_RATE(_patient); +private _hrIncrease = [_hrIncreaseLow, _hrIncreaseNormal, _hrIncreaseHigh] select (floor ((0 max _heartRate min 110) / 55)); +_hrIncrease params ["_minIncrease", "_maxIncrease"]; +private _heartRateChange = _minIncrease + random (_maxIncrease - _minIncrease); + +// Adjust the medication effects and add the medication to the list +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); diff --git a/addons/medical_treatment/functions/fnc_onMedicationUsage.sqf b/addons/medical_treatment/functions/fnc_onMedicationUsage.sqf index 6cbcf48f5a..1f9ef981dd 100644 --- a/addons/medical_treatment/functions/fnc_onMedicationUsage.sqf +++ b/addons/medical_treatment/functions/fnc_onMedicationUsage.sqf @@ -6,7 +6,7 @@ * Arguments: * 0: The patient * 1: Medication Treatment classname - * 2: Max dosage + * 2: Max dosage (0 to ignore) * 3: Incompatable medication > * * Return Value: @@ -18,40 +18,28 @@ * Public: No */ -params ["_target", "_className", "_maxDosage", "_incompatabileMeds"]; -TRACE_4("onMedicationUsage",_target,_className,_maxDosage,_incompatabileMeds); - -private _fnc_getMedicationCount = { - params ["_target", "_medication"]; - private _return = 0; - { - _x params ["_xMed", "_timeAdded", "_timeTillMaxEffect", "_maxTimeInSystem"]; - if (_xMed == _medication) then { - private _timeInSystem = CBA_missionTime - _timeAdded; - _return = _return + linearConversion [_timeTillMaxEffect, _maxTimeInSystem, _timeInSystem, 1, 0, true]; - }; - } forEach (_target getVariable [VAR_MEDICATIONS, []]); - TRACE_2("getMedicationCount",_medication,_return); - _return -}; +params ["_target", "_className", "_maxDosage", "_incompatibleMedication"]; +TRACE_4("onMedicationUsage",_target,_className,_maxDosage,_incompatibleMedication); private _overdosedMedications = []; // Check for overdose from current medication -private _currentDose = [_target, _className] call _fnc_getMedicationCount; -if (_currentDose >= floor (_maxDosage + round(random(2))) && {_maxDosage >= 1}) then { - TRACE_1("exceeded max dose",_currentDose); - _overdosedMedications pushBackUnique _className; +if (_maxDosage > 0) then { + private _currentDose = [_target, _className] call EFUNC(medical_status,getMedicationCount); + if (_currentDose >= floor (_maxDosage + round(random(2)))) then { + TRACE_1("exceeded max dose",_currentDose); + _overdosedMedications pushBackUnique _className; + }; }; // Check incompatible medication (format [med,limit]) { _x params ["_xMed", "_xLimit"]; - private _inSystem = [_target, _xMed] call _fnc_getMedicationCount; + private _inSystem = [_target, _xMed] call EFUNC(medical_status,getMedicationCount); if (_inSystem> _xLimit) then { _overdosedMedications pushBackUnique _xMed; }; -} forEach _incompatabileMeds; +} forEach _incompatibleMedication; if !(_overdosedMedications isEqualTo []) then { private _medicationConfig = (configFile >> "ace_medical_treatment" >> "Medication"); diff --git a/addons/medical_treatment/functions/fnc_placeInBodyBag.sqf b/addons/medical_treatment/functions/fnc_placeInBodyBag.sqf new file mode 100644 index 0000000000..02feb52025 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_placeInBodyBag.sqf @@ -0,0 +1,48 @@ +#include "script_component.hpp" +/* + * Author: Glowbal + * Places a dead body inside a body bag. + * + * Arguments: + * 0: Medic (not used) + * 1: Patient + * + * Return Value: + * None + * + * Example: + * [player, cursorObject] call ace_medical_treatment_fnc_placeInBodyBag + * + * Public: No + */ + +params ["", "_patient"]; +TRACE_1("placeInBodyBag",_patient); + +if (!local _patient) exitWith { + TRACE_1("Calling where local",local _patient); + [QGVAR(placeInBodyBag), [nil, _patient], _patient] call CBA_fnc_targetEvent; +}; + +if (alive _patient) then { + TRACE_1("Manually killing with setDead",_patient); + [_patient, "buried_alive"] call EFUNC(medical_status,setDead); +}; + +private _position = (getPosASL _patient) vectorAdd [0, 0, 0.2]; + +private _headPos = _patient modelToWorldVisual (_patient selectionPosition "head"); +private _spinePos = _patient modelToWorldVisual (_patient selectionPosition "Spine3"); +private _direction = (_headPos vectorFromTo _spinePos) call CBA_fnc_vectDir; + +// Move the body away so it won't collide with the body bag object +// This setPosASL seems to need to be called where the unit is local +_patient setPosASL [-5000, -5000, 0]; + +// Create the body bag object, set its position to prevent it from flipping +private _bodyBag = createVehicle ["ACE_bodyBagObject", [0, 0, 0], [], 0, "NONE"]; +_bodyBag setPosASL _position; +_bodyBag setDir _direction; + +// Server will handle hiding and deleting the body +["ace_placedInBodyBag", [_patient, _bodyBag]] call CBA_fnc_globalEvent; diff --git a/addons/medical_treatment/functions/fnc_removeBody.sqf b/addons/medical_treatment/functions/fnc_removeBody.sqf new file mode 100644 index 0000000000..e86d374e8e --- /dev/null +++ b/addons/medical_treatment/functions/fnc_removeBody.sqf @@ -0,0 +1,35 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Removes a body. Ideally it is deleted the next frame. + * However, player bodies cannot be deleted until they respawn, so it is hidden and deleted later. + * + * Arguments: + * 0: Body + * + * Return Value: + * None + * + * Example: + * [cursorObject] call ace_medical_treatment_fnc_removeBody + * + * Public: No + */ + +params ["_body"]; +TRACE_2("removeBody",_body,isPlayer _body); + +// Hide the body globally +[QEGVAR(common,hideObjectGlobal), [_body, true]] call CBA_fnc_serverEvent; + +// Add body to array of those waiting for deletion +if (isNil QGVAR(bodiesToDelete)) then { + GVAR(bodiesToDelete) = []; +}; + +GVAR(bodiesToDelete) pushBack _body; + +// Start up the body cleanup loop to delete bodies once they are free +if (count GVAR(bodiesToDelete) == 1) then { + [] call FUNC(bodyCleanupLoop); +}; diff --git a/addons/medical_treatment/functions/fnc_serverRemoveBody.sqf b/addons/medical_treatment/functions/fnc_serverRemoveBody.sqf deleted file mode 100644 index aa29cbc982..0000000000 --- a/addons/medical_treatment/functions/fnc_serverRemoveBody.sqf +++ /dev/null @@ -1,33 +0,0 @@ -#include "script_component.hpp" -/* - * Author: PabstMirror - * Removes corpse. Idealy it is just deleted the next frame, - * but player bodies cannot be deleted until they respawn, so it is hidden and deleted later. - * - * Arguments: - * 0: Mr Body - * - * Return Value: - * None - * - * Example: - * [cursorTarget] call ace_medical_treatment_fnc_serverRemoveBody - * - * Public: No - */ - -params ["_target"]; -TRACE_2("",_target,isPlayer _target); - -// Hide the body globaly -[QEGVAR(common,hideObjectGlobal), [_target, true]] call CBA_fnc_serverEvent; - -if (isNil QGVAR(bodiesToDelete)) then {GVAR(bodiesToDelete) = [];}; -GVAR(bodiesToDelete) pushBack _target; - -// Start up a loop to wait for bodies to be free to delete -if ((count GVAR(bodiesToDelete)) == 1) then { - [] call FUNC(bodyCleanupLoop); -}; - -nil diff --git a/addons/medical_treatment/functions/fnc_splint.sqf b/addons/medical_treatment/functions/fnc_splint.sqf new file mode 100644 index 0000000000..f7883da86a --- /dev/null +++ b/addons/medical_treatment/functions/fnc_splint.sqf @@ -0,0 +1,23 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Applies a splint to the patient on the given body part. + * + * Arguments: + * 0: Medic + * 1: Patient + * 2: Body Part + * + * Return Value: + * Nothing + * + * Example: + * [player, cursorObject, "LeftLeg"] call ace_medical_treatment_fnc_splint + * + * Public: No + */ + +params ["_medic", "_patient", "_bodyPart"]; +TRACE_3("splint",_medic,_patient,_bodyPart); + +[QGVAR(splintLocal), [_medic, _patient, _bodyPart], _patient] call CBA_fnc_targetEvent; diff --git a/addons/medical_treatment/functions/fnc_splintLocal.sqf b/addons/medical_treatment/functions/fnc_splintLocal.sqf new file mode 100644 index 0000000000..f0834b328e --- /dev/null +++ b/addons/medical_treatment/functions/fnc_splintLocal.sqf @@ -0,0 +1,33 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Local callback for applying a splint to a patient. + * + * Arguments: + * 0: Medic + * 1: Patient + * 2: Body Part + * + * Return Value: + * Nothing + * + * Example: + * [player, cursorObject, "LeftLeg"] call ace_medical_treatment_fnc_splintLocal + * + * Public: No + */ + +params ["_medic", "_patient", "_bodyPart"]; +TRACE_3("splintLocal",_medic,_patient,_bodyPart); + +private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; + +private _fractures = GET_FRACTURES(_patient); +_fractures set [_partIndex, -1]; +_patient setVariable [VAR_FRACTURES, _fractures, true]; + +// Check if we fixed limping from this treatment +[_patient] call EFUNC(medical_engine,updateDamageEffects); + +[_patient, "ACE_splint"] call FUNC(addToTriageCard); +[_patient, "activity", LSTRING(Activity_appliedSplint), [[_medic, false, true] call EFUNC(common,getName)]] call FUNC(addToLog); diff --git a/addons/medical_treatment/functions/fnc_surgicalKitProgress.sqf b/addons/medical_treatment/functions/fnc_surgicalKitProgress.sqf new file mode 100644 index 0000000000..9dcd7265e1 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_surgicalKitProgress.sqf @@ -0,0 +1,63 @@ +#include "script_component.hpp" +/* + * Author: BaerMitUmlaut, mharis001 + * Handles the surgical kit treatment by periodically closing bandaged wounds. + * + * Arguments: + * 0: Arguments + * 0: Medic (not used) + * 1: Patient + * 1: Elapsed Time + * 2: Total Time + * + * Return Value: + * Continue Treatment + * + * Example: + * [[objNull, player], 5, 10] call ace_medical_treatment_fnc_surgicalKitProgress + * + * Public: No + */ + +params ["_args", "_elapsedTime", "_totalTime"]; +_args params ["", "_patient"]; + +private _stitchableWounds = _patient call FUNC(getStitchableWounds); + +// Stop treatment if there are no wounds that can be stitched remaining +if (_stitchableWounds isEqualTo []) exitWith {false}; + +// Not enough time has elapsed to stitch a wound +if (_totalTime - _elapsedTime > (count _stitchableWounds - 1) * WOUND_STITCH_TIME) exitWith {true}; + +private _bandagedWounds = GET_BANDAGED_WOUNDS(_patient); +private _stitchedWounds = GET_STITCHED_WOUNDS(_patient); + +// Remove the first stitchable wound from the bandaged wounds +private _treatedWound = _bandagedWounds deleteAt (_bandagedWounds find (_stitchableWounds select 0)); +_treatedWound params ["_treatedID", "_treatedBodyPartN", "_treatedAmountOf"]; + +// Check if we need to add a new stitched wound or increase the amount of an existing one +private _woundIndex = _stitchedWounds findIf { + _x params ["_classID", "_bodyPartN"]; + + _classID == _treatedID && {_bodyPartN == _treatedBodyPartN} +}; + +if (_woundIndex == -1) then { + _stitchedWounds pushBack _treatedWound; +} else { + private _wound = _stitchedWounds select _woundIndex; + _wound set [2, (_wound select 2) + _treatedAmountOf]; +}; + +_patient setVariable [VAR_BANDAGED_WOUNDS, _bandagedWounds, true]; +_patient setVariable [VAR_STITCHED_WOUNDS, _stitchedWounds, true]; + +// Check if we fixed limping by stitching this wound (only for leg wounds) +if (EGVAR(medical,limping) == 2 && {_patient getVariable [QEGVAR(medical,isLimping), false]} && {_treatedBodyPartN > 3}) then { + TRACE_3("Updating damage effects",_patient,_treatedBodyPartN,local _patient); + [QEGVAR(medical_engine,updateDamageEffects), _patient, _patient] call CBA_fnc_targetEvent; +}; + +true diff --git a/addons/medical_treatment/functions/fnc_tourniquet.sqf b/addons/medical_treatment/functions/fnc_tourniquet.sqf new file mode 100644 index 0000000000..155a2c502b --- /dev/null +++ b/addons/medical_treatment/functions/fnc_tourniquet.sqf @@ -0,0 +1,33 @@ +#include "script_component.hpp" +/* + * Author: Glowbal, mharis001 + * Applies a tourniquet to the patient on the given body part. + * + * Arguments: + * 0: Medic + * 1: Patient + * 2: Body Part + * 3: Treatment (not used) + * 4: Item User (not used) + * 5: Used Item + * + * Return Value: + * None + * + * Example: + * [player, cursorObject, "LeftLeg", "", objNull, "ACE_tourniquet"] call ace_medical_treatment_fnc_tourniquet + * + * Public: No + */ + +params ["_medic", "_patient", "_bodyPart", "", "", "_usedItem"]; + +// Exit if there is a tourniquet already applied to body part +if ([_patient, _bodyPart] call FUNC(hasTourniquetAppliedTo)) exitWith { + ["There is already a tourniquet on this body part!", 1.5] call EFUNC(common,displayTextStructured); // todo: localize +}; + +[_patient, _usedItem] call FUNC(addToTriageCard); +[_patient, "activity", LSTRING(Activity_appliedTourniquet), [[_medic, false, true] call EFUNC(common,getName)]] call FUNC(addToLog); + +[QGVAR(tourniquetLocal), [_patient, _bodyPart], _patient] call CBA_fnc_targetEvent; diff --git a/addons/medical_treatment/functions/fnc_tourniquetLocal.sqf b/addons/medical_treatment/functions/fnc_tourniquetLocal.sqf new file mode 100644 index 0000000000..4bc803a8a8 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_tourniquetLocal.sqf @@ -0,0 +1,28 @@ +#include "script_component.hpp" +/* + * Author: Glowbal + * Local callback for applying a tourniquet to a patient. + * + * Arguments: + * 0: Patient + * 1: Body Part + * + * Return Value: + * None + * + * Example: + * [player, "LeftLeg"] call ace_medical_treatment_fnc_tourniquetLocal + * + * Public: No + */ + +params ["_patient", "_bodyPart"]; +TRACE_2("tourniquetLocal",_patient,_bodyPart); + +private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; + +private _tourniquets = GET_TOURNIQUETS(_patient); +_tourniquets set [_partIndex, CBA_missionTime]; +_patient setVariable [VAR_TOURNIQUET, _tourniquets, true]; + +[_patient] call EFUNC(medical_status,updateWoundBloodLoss); diff --git a/addons/medical_treatment/functions/fnc_tourniquetRemove.sqf b/addons/medical_treatment/functions/fnc_tourniquetRemove.sqf new file mode 100644 index 0000000000..50f4c084c0 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_tourniquetRemove.sqf @@ -0,0 +1,59 @@ +#include "script_component.hpp" +/* + * Author: Glowbal, mharis001 + * Removes the tourniquet from the patient on the given body part. + * + * Arguments: + * 0: Medic + * 1: Patient + * 2: Body Part + * + * Return Value: + * None + * + * Example: + * [player, cursorObject, "LeftLeg"] call ace_medical_treatment_fnc_tourniquetRemove + * + * Public: No + */ + +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 _tourniquets = GET_TOURNIQUETS(_patient); + +if (_tourniquets select _partIndex == 0) exitWith { + [LSTRING(noTourniquetOnBodyPart), 1.5] call EFUNC(common,displayTextStructured); +}; + +_tourniquets set [_partIndex, 0]; +_patient setVariable [VAR_TOURNIQUET, _tourniquets, true]; + +[_patient] call EFUNC(medical_status,updateWoundBloodLoss); + +// Add tourniquet item to medic's inventory +// todo: should there be a setting to select who receives the removed tourniquet? +[_medic, "ACE_tourniquet", true] call EFUNC(common,addToInventory); + +// Handle occluded medications that were blocked due to tourniquet +private _occludedMedications = _patient getVariable [QEGVAR(medical,occludedMedications), []]; +private _arrayModified = false; + +{ + _x params ["_bodyPartN", "_medication"]; + + if (_partIndex == _bodyPartN) then { + TRACE_1("delayed medication call after tourniquet removeal",_x); + [QGVAR(medicationLocal), [_patient, _bodyPart, _medication], _patient] call CBA_fnc_targetEvent; + _occludedMedications set [_forEachIndex, []]; + _arrayModified = true; + }; + +} forEach _occludedMedications; + +if (_arrayModified) then { + _occludedMedications = _occludedMedications - [[]]; + _patient setVariable [QEGVAR(medical,occludedMedications), _occludedMedications, true]; +}; diff --git a/addons/medical_treatment/functions/fnc_treatment.sqf b/addons/medical_treatment/functions/fnc_treatment.sqf index b76e6799ee..93c9877ad7 100644 --- a/addons/medical_treatment/functions/fnc_treatment.sqf +++ b/addons/medical_treatment/functions/fnc_treatment.sqf @@ -1,199 +1,150 @@ #include "script_component.hpp" /* - * Author: Glowbal, KoffeinFlummi - * Starts the treatment process + * Author: Glowbal, KoffeinFlummi, mharis001 + * Starts the treatment process. * * Arguments: - * 0: The medic - * 1: The patient - * 2: Body part - * 3: Treatment class name + * 0: Medic + * 1: Patient + * 2: Body Part + * 3: Treatment * * Return Value: - * Succesful treatment started + * Treatment Started + * + * Example: + * [player, cursorObject, "Head", "BasicBandage"] call ace_medical_treatment_fnc_treatment * * Public: No */ -params ["_caller", "_target", "_bodyPart", "_className"]; +params ["_medic", "_patient", "_bodyPart", "_classname"]; -// if the cursorMenu is open, the loading bar will fail. If we execute the function one frame later, it will work fine +// Delay by a frame if cursor menu is open to prevent progress bar failing if (uiNamespace getVariable [QEGVAR(interact_menu,cursorMenuOpened), false]) exitWith { - [DFUNC(treatment), _this] call CBA_fnc_execNextFrame; + [FUNC(treatment), _this] call CBA_fnc_execNextFrame; }; -if !([_caller, _target, _bodyPart, _className] call FUNC(canTreat)) exitWith {false}; +if !(_this call FUNC(canTreat)) exitWith {false}; -private _config = configFile >> QGVAR(Actions) >> _className; -private _isSelf = _caller isEqualTo _target; +private _config = configFile >> QGVAR(actions) >> _classname; -// handle items -private _items = getArray (_config >> "items"); +// Get treatment time from config, exit if treatment time is zero +private _treatmentTime = if (isText (_config >> "treatmentTime")) then { + GET_FUNCTION(_treatmentTime,_config >> "treatmentTime"); -private _consumeItems = 0; - -if (isNumber (_config >> "itemConsumed")) then { - _consumeItems = getNumber (_config >> "itemConsumed"); -} else { - if (isText (_config >> "itemConsumed")) then { - _consumeItems = missionNamespace getVariable [getText (_config >> "itemConsumed"), 0]; + if (_treatmentTime isEqualType {}) then { + _treatmentTime = call _treatmentTime; }; -}; -private _usersOfItems = []; - -if (_consumeItems > 0) then { - _usersOfItems = ([_caller, _target, _items] call FUNC(useItems)) select 1; -}; - -// parse the config for the progress callback -private _callbackProgress = getText (_config >> "callbackProgress"); - -if (_callbackProgress isEqualTo "") then { - _callbackProgress = "true"; -}; - -if (isNil _callbackProgress) then { - _callbackProgress = compile _callbackProgress; + _treatmentTime } else { - _callbackProgress = missionNamespace getVariable _callbackProgress; + getNumber (_config >> "treatmentTime"); }; -// play animation -private _callerAnim = if (_isSelf) then { - getText (_config >> ["animationCallerSelf", "animationCallerSelfProne"] select (stance _caller == "PRONE")); +if (_treatmentTime == 0) exitWith {false}; + +// Consume one of the treatment items if needed +// Store item user so that used item can be returned on failure +private _userAndItem = if (GET_NUMBER_ENTRY(_config >> "consumeItem") == 1) then { + [_medic, _patient, getArray (_config >> "items")] call FUNC(useItem); } else { - getText (_config >> ["animationCaller", "animationCallerProne"] select (stance _caller == "PRONE")); + [objNull, ""]; // Treatment does not require items to be consumed }; -_caller setVariable [QGVAR(selectedWeaponOnTreatment), weaponState _caller]; +_userAndItem params ["_itemUser", "_usedItem"]; -private _wpn = ["non", "rfl", "lnr", "pst"] param [["", primaryWeapon _caller, secondaryWeapon _caller, handgunWeapon _caller] find currentWeapon _caller, "non"]; - -_callerAnim = [_callerAnim, "[wpn]", _wpn] call CBA_fnc_replace; - -// this one is missing -if (_callerAnim == "AinvPknlMstpSlayWlnrDnon_medic") then { - _callerAnim = "AinvPknlMstpSlayWlnrDnon_medicOther"; +// 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 _animDuration = GVAR(animDurations) getVariable _callerAnim; +_medic setVariable [QGVAR(selectedWeaponOnTreatment), weaponState _medic]; -// these animations have transitions that take a bit longer... -if (weaponLowered _caller) then { +// 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; + +// This animation is missing, use alternative +if (_medicAnim == "AinvPknlMstpSlayWlnrDnon_medic") then { + _medicAnim = "AinvPknlMstpSlayWlnrDnon_medicOther"; +}; + +// 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; +}; + +// 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 _caller != "" && {_callerAnim != ""}) then { - _caller action ["WeaponInHand", _caller]; + // Fix problems with lowered weapon transitions by raising the weapon first + if (currentWeapon _medic != "" && {_medicAnim != ""}) then { + _medic action ["WeaponInHand", _medic]; }; }; -if (binocular _caller != "" && {binocular _caller == currentWeapon _caller}) then { - _animDuration = _animDuration + 1.0; +if (binocular _medic != "" && {binocular _medic == currentWeapon _medic}) then { + _animDuration = _animDuration + 1; }; -if (vehicle _caller == _caller && {_callerAnim != ""}) then { +// Play treatment animation for medic and determine the ending animation +if (vehicle _medic == _medic && {_medicAnim != ""}) then { private _endInAnim = "AmovP[pos]MstpS[stn]W[wpn]Dnon"; - private _pos = ["knl", "pne"] select (stance _caller == "PRONE"); + private _pos = ["knl", "pne"] select (stance _medic == "PRONE"); private _stn = "non"; if (_wpn != "non") then { - _stn = ["ras", "low"] select (weaponLowered _caller); + _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; - TRACE_1("",_endInAnim); - [_caller, _callerAnim] call EFUNC(common,doAnimation); - [_caller, _endInAnim] call EFUNC(common,doAnimation); - _caller setVariable [QGVAR(endInAnim), _endInAnim]; -}; + [_medic, _medicAnim] call EFUNC(common,doAnimation); + [_medic, _endInAnim] call EFUNC(common,doAnimation); + _medic setVariable [QGVAR(endInAnim), _endInAnim]; -// get treatment time from config - also supports variables and code expressions -private _treatmentTime = 0; + // Speed up animation based on treatment time (but cap max to prevent odd animiations/cam shake) + private _animRatio = (_animDuration / _treatmentTime) min 3; + TRACE_3("setAnimSpeedCoef",_animRatio,_animDuration,_treatmentTime); + [QEGVAR(common,setAnimSpeedCoef), [_medic, _animRatio]] call CBA_fnc_globalEvent; -if (isNumber (_config >> "treatmentTime")) then { - _treatmentTime = getNumber (_config >> "treatmentTime"); -} else { - if (isText (_config >> "treatmentTime")) then { - _treatmentTime = getText (_config >> "treatmentTime"); - - if (isNil _treatmentTime) then { - _treatmentTime = compile _treatmentTime; - } else { - _treatmentTime = missionNamespace getVariable _treatmentTime; - }; - - if !(_treatmentTime isEqualType 0) then { - _treatmentTime = call _treatmentTime; - }; + if (!isNil QEGVAR(advanced_fatigue,setAnimExclusions)) then { + EGVAR(advanced_fatigue,setAnimExclusions) pushBack QUOTE(ADDON); }; }; -TRACE_1("",_treatmentTime); -if (_treatmentTime == 0) exitWith { false }; - -// speed up animation depending on treatment time -if (!isNil "_animDuration") then { - [QEGVAR(common,setAnimSpeedCoef), [_caller, _animDuration / _treatmentTime]] call CBA_fnc_globalEvent; - TRACE_2("",_animDuration,_treatmentTime); -}; - -// play sound +// Play a random treatment sound globally if defined if (isArray (_config >> "sounds")) then { - selectRandom getArray (_config >> "sounds") params ["_file", ["_volume", 1], ["_pitch", 1], ["_distance", 0]]; - TRACE_4("playSound3D",_file,_volume,_pitch,_distance); - playSound3D [ - _file, - objNull, - false, - getPosASL _caller, - _volume, - _pitch, - _distance - ]; + selectRandom getArray (_config >> "sounds") params ["_file", ["_volume", 1], ["_pitch", 1], ["_distance", 10]]; + playSound3D [_file, objNull, false, getPosASL _medic, _volume, _pitch, _distance]; }; -private _startCallback = getText (_config >> "callbackStart"); -if (isNil _startCallback) then { - _startCallback = compile _startCallback; -} else { - _startCallback = missionNamespace getVariable _startCallback; +GET_FUNCTION(_callbackStart,_config >> "callbackStart"); +GET_FUNCTION(_callbackProgress,_config >> "callbackProgress"); + +if (_callbackProgress isEqualTo {}) then { + _callbackProgress = {true}; }; -if !(_startCallback isEqualType {}) then { - _startCallback = {TRACE_1("startCallback was NOT code",_startCallback)}; -}; +[_medic, _patient, _bodyPart, _classname, _itemUser, _usedItem] call _callbackStart; -[_caller, _target, _bodyPart, _className, _items, _usersOfItems] call _startCallback; - -// start treatment [ _treatmentTime, - [_caller, _target, _bodyPart, _className, _items, _usersOfItems], - DFUNC(treatment_success), - DFUNC(treatment_failure), + [_medic, _patient, _bodyPart, _classname, _itemUser, _usedItem], + FUNC(treatmentSuccess), + FUNC(treatmentFailure), getText (_config >> "displayNameProgress"), _callbackProgress, - ["isnotinside"] + ["isNotInside"] ] call EFUNC(common,progressBar); -// display icon -private _iconDisplayed = getText (_config >> "actionIconPath"); - -if (_iconDisplayed != "") then { - [QGVAR(treatmentActionIcon), true, _iconDisplayed, [1,1,1,1], getNumber (_config >> "actionIconDisplayTime")] call EFUNC(common,displayIcon); -}; - -// handle display of text/hints -private _displayText = getText (_config >> ["displayTextOther", "displayTextSelf"] select _isSelf); - -if (_displayText != "") then { - [QEGVAR(common,displayTextStructured), [[_displayText, _caller call EFUNC(common,getName), _target call EFUNC(common,getName)], 1.5, _caller], _caller] call CBA_fnc_targetEvent; -}; - true diff --git a/addons/medical_treatment/functions/fnc_treatmentBandage.sqf b/addons/medical_treatment/functions/fnc_treatmentBandage.sqf deleted file mode 100644 index bb4ac5ed9b..0000000000 --- a/addons/medical_treatment/functions/fnc_treatmentBandage.sqf +++ /dev/null @@ -1,26 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal - * Bandage treatment callback - * - * Arguments: - * 0: The medic - * 1: The patient - * 2: Body part - * 3: Treatment class name - * 4: Item - * - * Return Value: - * Succesful treatment started - * - * Public: No - */ - -params ["_caller", "_target", "_bodyPart", "_className", "_items"]; - -[_target, "activity", ELSTRING(medical_treatment,Activity_bandagedPatient), [[_caller, false, true] call EFUNC(common,getName)]] call FUNC(addToLog); -[_target, "activity_view", ELSTRING(medical_treatment,Activity_bandagedPatient), [[_caller, false, true] call EFUNC(common,getName)]] call FUNC(addToLog); // TODO expand message - -[QGVAR(treatmentBandageLocal), [_target, _className, _bodyPart], _target] call CBA_fnc_targetEvent; - -true diff --git a/addons/medical_treatment/functions/fnc_treatmentBandageLocal.sqf b/addons/medical_treatment/functions/fnc_treatmentBandageLocal.sqf deleted file mode 100644 index 92bb26e5ca..0000000000 --- a/addons/medical_treatment/functions/fnc_treatmentBandageLocal.sqf +++ /dev/null @@ -1,48 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal - * Handles the bandage of a patient. - * - * Arguments: - * 0: The patient - * 1: Treatment class name - * 2: Body part - * - * Return Value: - * Succesful treatment started - * - * Public: No - */ - -params ["_target", "_bandage", "_bodyPart"]; - -private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; -if (_partIndex < 0) exitWith { false }; - -private _openWounds = _target getVariable [QEGVAR(medical,openWounds), []]; -if (_openWounds isEqualTo []) exitWith { false }; - -// Figure out which injury for this bodypart is the best choice to bandage -// TODO also use up the remainder on left over injuries -private _targetWound = [_target, _bandage, _partIndex] call FUNC(findMostEffectiveWound); -_targetWound params ["_wound", "_woundIndex", "_effectiveness"]; - -// Everything is patched up on this body part already -if (_effectiveness == -1) exitWith {}; - -// Find the impact this bandage has and reduce the amount this injury is present -private _amountOf = _wound select 3; -private _impact = _effectiveness min _amountOf; -_wound set [3, _amountOf - _impact]; -_openWounds set [_woundIndex, _wound]; - -_target setVariable [QEGVAR(medical,openWounds), _openWounds, true]; - -[_target] call EFUNC(medical_status,updateWoundBloodLoss); - -// Handle the reopening of bandaged wounds -if (_impact > 0 && {GVAR(advancedBandages) && {GVAR(woundReopening)}}) then { - [_target, _impact, _partIndex, _woundIndex, _wound, _bandage] call FUNC(handleBandageOpening); -}; - -true diff --git a/addons/medical_treatment/functions/fnc_treatmentCPR.sqf b/addons/medical_treatment/functions/fnc_treatmentCPR.sqf deleted file mode 100644 index 69adc04bc6..0000000000 --- a/addons/medical_treatment/functions/fnc_treatmentCPR.sqf +++ /dev/null @@ -1,30 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal - * Callback for the CPR treatment action on success. - * - * Arguments: - * 0: The medic - * 1: The patient - * 2: Body part - * 3: Treatment class name - * - * Return Value: - * Succesful treatment started - * - * Public: No - */ - -params ["_caller", "_target", "_selectionName", "_className", "_items"]; - -_target setVariable [VAR_HEART_RATE, 0, true]; -_target setVariable [QGVAR(receiveCPR), false, true]; // CPR finished -[_target] call FUNC(calculateBlood); - -if (alive _target && {IN_CRDC_ARRST(_target)}) then { - [_target, "activity_view", ELSTRING(medical_treatment,Activity_cpr), [[_caller, false, true] call EFUNC(common,getName)]] call FUNC(addToLog); - - [QGVAR(treatmentCPRLocal), [_caller, _target], _target] call CBA_fnc_targetEvent; -}; - -true diff --git a/addons/medical_treatment/functions/fnc_treatmentCPRLocal.sqf b/addons/medical_treatment/functions/fnc_treatmentCPRLocal.sqf deleted file mode 100644 index 58d882d927..0000000000 --- a/addons/medical_treatment/functions/fnc_treatmentCPRLocal.sqf +++ /dev/null @@ -1,25 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal - * local Callback for the CPR treatment action on success. - * - * Arguments: - * 0: The medic - * 1: The patient - * - * Return Value: - * Succesful treatment started - * - * Public: No - */ - -params ["_caller", "_target"]; - -if ((random 1) >= 0.6) then { - [QEGVAR(medical,CPRSucceeded), _target] call CBA_fnc_localEvent; -}; - -[_target, "activity", ELSTRING(medical_treatment,Activity_CPR), [[_caller, false, true] call EFUNC(common,getName)]] call FUNC(addToLog); -[_target, "activity_view", ELSTRING(medical_treatment,Activity_CPR), [[_caller, false, true] call EFUNC(common,getName)]] call FUNC(addToLog); // TODO expand message - -true diff --git a/addons/medical_treatment/functions/fnc_treatmentCPR_failure.sqf b/addons/medical_treatment/functions/fnc_treatmentCPR_failure.sqf deleted file mode 100644 index a09dfccba4..0000000000 --- a/addons/medical_treatment/functions/fnc_treatmentCPR_failure.sqf +++ /dev/null @@ -1,22 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Zakant - * Handles the failure of the CPR treatment. - * - * Arguments: - * 0: The medic - * 1: The patient - * - * Return Value: - * None - * - * Public: No - */ - -params ["_caller", "_target"]; - -if (!(_target call EFUNC(common,isAwake)) || {IN_CRDC_ARRST(_target)}) then { - _target setVariable [VAR_HEART_RATE, 0, true]; -}; -_target setVariable [QGVAR(receiveCPR), false, true]; -[_target] call FUNC(calculateBlood); diff --git a/addons/medical_treatment/functions/fnc_treatmentCPR_progress.sqf b/addons/medical_treatment/functions/fnc_treatmentCPR_progress.sqf deleted file mode 100644 index f03f9708fd..0000000000 --- a/addons/medical_treatment/functions/fnc_treatmentCPR_progress.sqf +++ /dev/null @@ -1,28 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Zakant - * Handles the progress of the CPR treatment. - * - * Arguments: - * 0: Arguments - * 0: Caller - * 1: Target - * 1: Elapsed Time - * 2: Total Time - * - * Return Value: - * May Treatment continue - * - * Public: No - */ - -params ["_args", "_elapsedTime", "_totalTime"]; -_args params ["_caller", "_target"]; - -// If the patient awakes by mysterious force, no cpr is needed! -if (_target call EFUNC(common,isAwake)) exitWith {false}; -if !IN_CRDC_ARRST(_target) exitWith {false}; - -[_target] call FUNC(calculateBlood); // Calculate blood volume. If their is no pulse, nothing happens! - -true diff --git a/addons/medical_treatment/functions/fnc_treatmentCPR_start.sqf b/addons/medical_treatment/functions/fnc_treatmentCPR_start.sqf deleted file mode 100644 index 642cd722a0..0000000000 --- a/addons/medical_treatment/functions/fnc_treatmentCPR_start.sqf +++ /dev/null @@ -1,23 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Zakant - * Handles the start of the CPR treatment. - * - * Arguments: - * 0: The medic - * 1: The patient - * - * Return Value: - * None - * - * Public: No - */ - -params ["_caller", "_target"]; - -_target setVariable [QGVAR(receiveCPR), true, true]; // Target receives CPR -if (EGVAR(medical,CPRcreatesPulse) && {GET_HEART_RATE(_target) == 0}) then { - _target setVariable [VAR_HEART_RATE, round (30 + random [-5, 0, 5]) , true]; // And we have a (random) pulse -}; - -_target setVariable [QEGVAR(medical,lastTimeUpdated), CBA_missionTime, true]; diff --git a/addons/medical_treatment/functions/fnc_treatmentFailure.sqf b/addons/medical_treatment/functions/fnc_treatmentFailure.sqf new file mode 100644 index 0000000000..f59331fc77 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_treatmentFailure.sqf @@ -0,0 +1,50 @@ +#include "script_component.hpp" +/* + * Author: KoffeinFlummi, Glowbal, mharis001 + * Handles treatment process failure. + * + * Arguments: + * 0: Arguments + * 0: Medic + * 1: Patient + * 2: Body Part + * 3: Treatment + * 4: Item User + * 5: Used Item + * + * Return Value: + * None + * + * Public: No + */ + +params ["_args"]; +_args params ["_medic", "_patient", "_bodyPart", "_classname", "_itemUser", "_usedItem"]; + +// Return used item to user (if used) +if (!isNull _itemUser) then { + [_itemUser, _usedItem] call EFUNC(common,addToInventory); +}; + +// Switch medic to end animation immediately +private _endInAnim = _medic getVariable QGVAR(endInAnim); + +if (!isNil "_endInAnim") then { + if (animationState _medic != _endInAnim) then { + [_medic, _endInAnim, 2] call EFUNC(common,doAnimation); + }; + + _medic setVariable [QGVAR(endInAnim), nil]; +}; + +// Reset medic animation speed coefficient +[QEGVAR(common,setAnimSpeedCoef), [_medic, 1]] call CBA_fnc_globalEvent; + +if (!isNil QEGVAR(advanced_fatigue,setAnimExclusions)) then { + EGVAR(advanced_fatigue,setAnimExclusions) deleteAt (EGVAR(advanced_fatigue,setAnimExclusions) find QUOTE(ADDON)); +}; + +// Call treatment specific failure callback +GET_FUNCTION(_callbackFailure,configFile >> QGVAR(actions) >> _classname >> "callbackFailure"); + +_args call _callbackFailure; diff --git a/addons/medical_treatment/functions/fnc_treatmentFullHeal.sqf b/addons/medical_treatment/functions/fnc_treatmentFullHeal.sqf deleted file mode 100644 index 8499d4f525..0000000000 --- a/addons/medical_treatment/functions/fnc_treatmentFullHeal.sqf +++ /dev/null @@ -1,26 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal - * Full heal treatment - * - * Arguments: - * 0: The medic - * 1: The patient - * 2: Body part - * 3: Treatment class name - * 4: Item - * - * Return Value: - * Succesful treatment started - * - * Public: No - */ - -params ["_caller", "_target"]; - -[QGVAR(treatmentFullHealLocal), [_target], _target] call CBA_fnc_targetEvent; - -[_target, "activity", ELSTRING(medical_treatment,Activity_fullHeal), [[_caller, false, true] call EFUNC(common,getName)]] call FUNC(addToLog); -[_target, "activity_view", ELSTRING(medical_treatment,Activity_fullHeal), [[_caller, false, true] call EFUNC(common,getName)]] call FUNC(addToLog); // TODO expand message - -true diff --git a/addons/medical_treatment/functions/fnc_treatmentFullHealLocal.sqf b/addons/medical_treatment/functions/fnc_treatmentFullHealLocal.sqf deleted file mode 100644 index dfc712872b..0000000000 --- a/addons/medical_treatment/functions/fnc_treatmentFullHealLocal.sqf +++ /dev/null @@ -1,78 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal - * Handles full heal of a patient. - * - * Arguments: - * 0: The patient - * - * Return Value: - * Succesful treatment started - * - * Public: No - */ - -params ["_target"]; - -if (!alive _target) exitWith {}; - -// Treatment conditions would normally limit this to non-unconc units, but treatment event may be called externally (zeus) -if (_target getVariable [QEGVAR(medical,inCardiacArrest), false]) then { - TRACE_1("exiting cardiac arrest",_target); - [QEGVAR(medical,CPRSucceeded), _target] call CBA_fnc_localEvent; -}; -if (_target getVariable ["ACE_isUnconscious",false]) then { - TRACE_1("waking up",_target); // wake up first or unconc variables will be reset - [QEGVAR(medical,WakeUp), _target] call CBA_fnc_localEvent; -}; - - -_target setVariable [VAR_PAIN, 0, true]; -_target setVariable [VAR_BLOOD_VOL, DEFAULT_BLOOD_VOLUME, true]; - -// tourniquets -_target setVariable [VAR_TOURNIQUET, DEFAULT_TOURNIQUET_VALUES, true]; -_target setVariable [QGVAR(occludedMedications), nil, true]; - -// wounds and injuries -_target setVariable [QEGVAR(medical,openWounds), [], true]; -_target setVariable [QEGVAR(medical,bandagedWounds), [], true]; -_target setVariable [QEGVAR(medical,stitchedWounds), [], true]; -_target setVariable [QEGVAR(medical,isLimping), false, true]; - -// - Update wound bleeding -[_target] call EFUNC(medical_status,updateWoundBloodLoss); - -// vitals -_target setVariable [VAR_HEART_RATE, DEFAULT_HEART_RATE, true]; -_target setVariable [VAR_BLOOD_PRESS, [80, 120], true]; -_target setVariable [VAR_PERIPH_RES, DEFAULT_PERIPH_RES, true]; - -// IVs -_target setVariable [QEGVAR(medical,ivBags), nil, true]; - -// damage storage -_target setVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0], true]; -#ifdef DEBUG_TESTRESULTS -_target setVariable [QEGVAR(medical,bodyPartStatus), [0,0,0,0,0,0], true]; -#endif - -// generic medical admin -_target setVariable [VAR_CRDC_ARRST, false, true]; -_target setVariable [VAR_UNCON, false, true]; -_target setVariable [VAR_HEMORRHAGE, 0, true]; -_target setVariable [VAR_IN_PAIN, false, true]; -_target setVariable [VAR_PAIN_SUPP, 0, true]; - -// medication -_target setVariable [VAR_MEDICATIONS, [], true]; - -// Reset triage card since medication is all reset -_target setVariable [QEGVAR(medical,triageCard), [], true]; - -[_target, false] call EFUNC(medical_engine,setLimping); - -// Resetting damage -_target setDamage 0; - -[QEGVAR(medical,FullHeal), _target] call CBA_fnc_localEvent; diff --git a/addons/medical_treatment/functions/fnc_treatmentIV.sqf b/addons/medical_treatment/functions/fnc_treatmentIV.sqf deleted file mode 100644 index e6f6be0e16..0000000000 --- a/addons/medical_treatment/functions/fnc_treatmentIV.sqf +++ /dev/null @@ -1,31 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal - * Patient IV Treatment callback - * - * Arguments: - * 0: The medic - * 1: The patient - * 2: Body part - * 3: Treatment class name - * 4: Item - * - * Return Value: - * Succesful treatment started - * - * Public: No - */ - -params ["_caller", "_target", "_bodyPart", "_className", "_items"]; - -if (_items isEqualTo []) exitWith {false}; - -_items params ["_removeItem"]; - -[QGVAR(treatmentIVLocal), [_target, _className, _bodyPart], _target] call CBA_fnc_targetEvent; - -[_target, _removeItem] call FUNC(addToTriageCard); -[_target, "activity", ELSTRING(medical_treatment,Activity_gaveIV), [[_caller, false, true] call EFUNC(common,getName)]] call FUNC(addToLog); -[_target, "activity_view", ELSTRING(medical_treatment,Activity_gaveIV), [[_caller, false, true] call EFUNC(common,getName)]] call FUNC(addToLog); // TODO expand message - -true diff --git a/addons/medical_treatment/functions/fnc_treatmentIVLocal.sqf b/addons/medical_treatment/functions/fnc_treatmentIVLocal.sqf deleted file mode 100644 index a7c3914313..0000000000 --- a/addons/medical_treatment/functions/fnc_treatmentIVLocal.sqf +++ /dev/null @@ -1,48 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal - * IV Treatment local callback - * - * Arguments: - * 0: The patient - * 1: Treatment class name - * 2: Body part - * - * Return Value: - * None - * - * Public: No - */ - -params ["_target", "_treatmentClassname", "_bodyPart"]; - -private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; -if (_partIndex < 0) exitWith { false }; - -private _bloodVolume = GET_BLOOD_VOLUME(_target); - -if (_bloodVolume >= DEFAULT_BLOOD_VOLUME) exitWith {}; - -// Find the proper attributes for the used IV -private _config = configFile >> QUOTE(ADDON) >> "IV"; -private _volumeAdded = getNumber (_config >> "volume"); -private _type = getText (_config >> "type"); - -if (isClass (_config >> _treatmentClassname)) then { - _config = _config >> _treatmentClassname; - - if (isNumber (_config >> "volume")) then { - _volumeAdded = getNumber (_config >> "volume"); - }; - - if (isText (_config >> "type")) then { - _type = getText (_config >> "type"); - }; -} else { - ERROR("IV Treatment Classname not found"); -}; - -private _bloodBags = _target getVariable [QEGVAR(medical,ivBags), []]; -_bloodBags pushBack [_volumeAdded, _type, _partIndex]; - -_target setVariable [QEGVAR(medical,ivBags), _bloodBags, true]; diff --git a/addons/medical_treatment/functions/fnc_treatmentMedication.sqf b/addons/medical_treatment/functions/fnc_treatmentMedication.sqf deleted file mode 100644 index 77fabe5bf8..0000000000 --- a/addons/medical_treatment/functions/fnc_treatmentMedication.sqf +++ /dev/null @@ -1,34 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal - * IV Treatment callback - * - * Arguments: - * 0: The medic - * 1: The patient - * 2: Body part - * 3: Treatment class name - * 4: Items Used - * - * Return Value: - * Succesful treatment started - * - * Public: No - */ - -params ["_caller", "_target", "_bodyPart", "_className", "_items"]; -TRACE_5("params",_caller,_target,_bodyPart,_className,_items); - -private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; - -[QGVAR(treatmentMedicationLocal), [_target, _className, _partIndex], _target] call CBA_fnc_targetEvent; - -{ - if (_x != "") then { - [_target, _x] call FUNC(addToTriageCard); - [_target, "activity", ELSTRING(medical_treatment,Activity_usedItem), [[_caller, false, true] call EFUNC(common,getName), getText (configFile >> "CfgWeapons" >> _x >> "displayName")]] call FUNC(addToLog); - [_target, "activity_view", ELSTRING(medical_treatment,Activity_usedItem), [[_caller, false, true] call EFUNC(common,getName), getText (configFile >> "CfgWeapons" >> _x >> "displayName")]] call FUNC(addToLog); - }; -} forEach _items; - -true diff --git a/addons/medical_treatment/functions/fnc_treatmentMedicationLocal.sqf b/addons/medical_treatment/functions/fnc_treatmentMedicationLocal.sqf deleted file mode 100644 index 2732b0f398..0000000000 --- a/addons/medical_treatment/functions/fnc_treatmentMedicationLocal.sqf +++ /dev/null @@ -1,87 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal - * Handles the medication given to a patient. - * - * Arguments: - * 0: The patient - * 1: Treatment class name - * 2: Injection Site Part Number - * - * Return Value: - * Succesful treatment started - * - * Example: - * [player, "Morphine", 2] call ace_medical_treatment_fnc_treatmentMedicationLocal - * - * Public: No - */ -#define MORPHINE_PAIN_SUPPRESSION 0.6 - -params ["_target", "_className", "_partIndex"]; -TRACE_3("treatmentMedicationLocal",_target,_className,_partIndex); - -if (!alive _target) exitWith {false}; - -if (!GVAR(advancedMedication)) exitWith { - TRACE_1("MedicalSettingAdvancedMedication is:", GVAR(advancedMedication)); - if (_className == "Morphine") exitWith { - private _painSupress = GET_PAIN_SUPPRESS(_target); - _target setVariable [VAR_PAIN_SUPP, (_painSupress + MORPHINE_PAIN_SUPPRESSION) min 1, true]; - }; - if (_className == "Epinephrine") exitWith { - [QEGVAR(medical,WakeUp), _target] call CBA_fnc_localEvent; - }; -}; -TRACE_1("Running treatmentMedicationLocal with Advanced configuration for", _target); - -private _tourniquets = GET_TOURNIQUETS(_target); - -if (_tourniquets select _partIndex > 0) exitWith { - TRACE_1("unit has tourniquets blocking blood flow on injection site",_tourniquets); - private _delayedMedications = _target getVariable [QEGVAR(medical,occludedMedications), []]; - - _delayedMedications pushBack _this; - _target setVariable [QEGVAR(medical,occludedMedications), _delayedMedications, true]; - - true -}; - -// Find the proper attributes for the used medication -private _medicationConfig = configFile >> QUOTE(ADDON) >> "Medication"; -private _painReduce = getNumber (_medicationConfig >> "painReduce"); -private _hrIncreaseLow = getArray (_medicationConfig >> "hrIncreaseLow"); -private _hrIncreaseNorm = getArray (_medicationConfig >> "hrIncreaseNormal"); -private _hrIncreaseHigh = getArray (_medicationConfig >> "hrIncreaseHigh"); -private _timeInSystem = getNumber (_medicationConfig >> "timeInSystem"); -private _timeTillMaxEffect = getNumber (_medicationConfig >> "timeTillMaxEffect"); -private _maxDose = getNumber (_medicationConfig >> "maxDose"); -private _viscosityChange = getNumber (_medicationConfig >> "viscosityChange"); -private _inCompatableMedication = []; - -if (isClass (_medicationConfig >> _className)) then { - _medicationConfig = _medicationConfig >> _className; - if (isNumber (_medicationConfig >> "painReduce")) then { _painReduce = getNumber (_medicationConfig >> "painReduce");}; - if (isArray (_medicationConfig >> "hrIncreaseLow")) then { _hrIncreaseLow = getArray (_medicationConfig >> "hrIncreaseLow"); }; - if (isArray (_medicationConfig >> "hrIncreaseNormal")) then { _hrIncreaseNorm = getArray (_medicationConfig >> "hrIncreaseNormal"); }; - if (isArray (_medicationConfig >> "hrIncreaseHigh")) then { _hrIncreaseHigh = getArray (_medicationConfig >> "hrIncreaseHigh"); }; - if (isNumber (_medicationConfig >> "timeInSystem")) then { _timeInSystem = getNumber (_medicationConfig >> "timeInSystem"); }; - if (isNumber (_medicationConfig >> "timeTillMaxEffect")) then { _timeTillMaxEffect = getNumber (_medicationConfig >> "timeTillMaxEffect"); }; - if (isNumber (_medicationConfig >> "maxDose")) then { _maxDose = getNumber (_medicationConfig >> "maxDose"); }; - if (isArray (_medicationConfig >> "inCompatableMedication")) then { _inCompatableMedication = getArray (_medicationConfig >> "inCompatableMedication"); }; - if (isNumber (_medicationConfig >> "viscosityChange")) then { _viscosityChange = getNumber (_medicationConfig >> "viscosityChange"); }; -}; - -private _heartRate = GET_HEART_RATE(_target); -private _hrIncrease = [_hrIncreaseLow, _hrIncreaseNorm, _hrIncreaseHigh] select (floor ((0 max _heartRate min 110) / 55)); -_hrIncrease params ["_minIncrease", "_maxIncrease"]; -private _heartRateChange = _minIncrease + random (_maxIncrease - _minIncrease); - -// Adjust the medication effects and add the medication to the list -TRACE_3("adjustments",_heartRateChange,_painReduce,_viscosityChange); -[_target, _className, _timeTillMaxEffect, _timeInSystem, _heartRateChange, _painReduce, _viscosityChange] call EFUNC(medical_status,addMedicationAdjustment); - -// Check for medication compatiblity -[_target, _className, _maxDose, _inCompatableMedication] call FUNC(onMedicationUsage); - -true diff --git a/addons/medical_treatment/functions/fnc_treatmentSuccess.sqf b/addons/medical_treatment/functions/fnc_treatmentSuccess.sqf new file mode 100644 index 0000000000..07dd5261b3 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_treatmentSuccess.sqf @@ -0,0 +1,51 @@ +#include "script_component.hpp" +/* + * Author: KoffeinFlummi, Glowbal, mharis001 + * Handles treatment process success. + * + * Arguments: + * 0: Arguments + * 0: Medic + * 1: Patient + * 2: Body Part + * 3: Treatment + * 4: Item User + * 5: Used Item + * + * Return Value: + * None + * + * Public: No + */ + +params ["_args"]; +_args params ["_medic", "_patient", "_bodyPart", "_classname"]; + +// Switch medic to end animation immediately +private _endInAnim = _medic getVariable QGVAR(endInAnim); + +if (!isNil "_endInAnim") then { + if (animationState _medic != _endInAnim) then { + [_medic, _endInAnim, 2] call EFUNC(common,doAnimation); + }; + + _medic setVariable [QGVAR(endInAnim), nil]; +}; + +// Reset medic animation speed coefficient +[QEGVAR(common,setAnimSpeedCoef), [_medic, 1]] call CBA_fnc_globalEvent; + +if (!isNil QEGVAR(advanced_fatigue,setAnimExclusions)) then { + EGVAR(advanced_fatigue,setAnimExclusions) deleteAt (EGVAR(advanced_fatigue,setAnimExclusions) find QUOTE(ADDON)); +}; + +// Call treatment specific success callback +GET_FUNCTION(_callbackSuccess,configFile >> QGVAR(actions) >> _classname >> "callbackSuccess"); + +_args call _callbackSuccess; + +// Call litter creation handler +_args call FUNC(createLitter); + +// Emit local event for medical API +["ace_treatmentSucceded", [_medic, _patient, _bodyPart, _classname]] call CBA_fnc_localEvent; diff --git a/addons/medical_treatment/functions/fnc_treatmentSurgicalKit_onProgress.sqf b/addons/medical_treatment/functions/fnc_treatmentSurgicalKit_onProgress.sqf deleted file mode 100644 index 17d5aff0b6..0000000000 --- a/addons/medical_treatment/functions/fnc_treatmentSurgicalKit_onProgress.sqf +++ /dev/null @@ -1,40 +0,0 @@ -#include "script_component.hpp" -/* - * Author: BaerMitUmlaut - * Handles treatment via surgical kit per frame - * - * Arguments: - * 0: Arguments - * 0: Caller - * 1: Target - * 1: Elapsed Time - * 2: Total Time - * - * Return Value: - * Succesful treatment started - * - * Example: - * [[bob, kevin], 5, 5] call ace_medical_treatment_fnc_treatmentAdvanced_surgicalKit_onProgress - * - * Public: No - */ - -params ["_args", "_elapsedTime", "_totalTime"]; -_args params ["_caller", "_target"]; - -private _bandagedWounds = _target getVariable [QEGVAR(medical,bandagedWounds), []]; -private _stitchedWounds = _target getVariable [QEGVAR(medical,stitchedWounds), []]; - -//In case two people stitch up one patient and the last wound has already been closed we can stop already -if (count _bandagedWounds == 0) exitWith { false }; - -//Has enough time elapsed that we can close another wound? -if (_totalTime - _elapsedTime <= (count _bandagedWounds - 1) * 5) then { - private _treatedWound = _bandagedWounds deleteAt 0; - _stitchedWounds pushBack _treatedWound; - _target setVariable [QEGVAR(medical,bandagedWounds), _bandagedWounds, true]; - _target setVariable [QEGVAR(medical,stitchedWounds), _stitchedWounds, true]; - TRACE_3("stitched",_treatedWound,count _bandagedWounds,count _stitchedWounds); -}; - -true diff --git a/addons/medical_treatment/functions/fnc_treatmentTourniquet.sqf b/addons/medical_treatment/functions/fnc_treatmentTourniquet.sqf deleted file mode 100644 index 595d55d589..0000000000 --- a/addons/medical_treatment/functions/fnc_treatmentTourniquet.sqf +++ /dev/null @@ -1,40 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal - * Apply a tourniquet to the patient - * - * Arguments: - * 0: The medic - * 1: The patient - * 2: Body part - * 3: Treatment class name - * - * Return Value: - * Succesful treatment started - * - * Public: No - */ - -params ["_caller", "_target", "_bodyPart", "_className", "_items"]; - -if (count _items == 0) exitWith {false}; - -private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; - -private _tourniquets = GET_TOURNIQUETS(_target); - -if (_tourniquets select _partIndex > 0) exitWith { - private _output = "There is already a tourniquet on this body part!"; // TODO localization - [QEGVAR(common,displayTextStructured), [_output, 1.5, _caller], _caller] call CBA_fnc_targetEvent; - false -}; - -private _removeItem = _items select 0; - -[QGVAR(treatmentTourniquetLocal), [_target, _removeItem, _bodyPart], _target] call CBA_fnc_targetEvent; - -[_target, _removeItem] call FUNC(addToTriageCard); -[_target, "activity", ELSTRING(medical_treatment,Activity_appliedTourniquet), [[_caller, false, true] call EFUNC(common,getName)]] call FUNC(addToLog); -[_target, "activity_view", ELSTRING(medical_treatment,Activity_appliedTourniquet), [[_caller, false, true] call EFUNC(common,getName)]] call FUNC(addToLog); // TODO expand message - -true diff --git a/addons/medical_treatment/functions/fnc_treatmentTourniquetLocal.sqf b/addons/medical_treatment/functions/fnc_treatmentTourniquetLocal.sqf deleted file mode 100644 index a3bd24d381..0000000000 --- a/addons/medical_treatment/functions/fnc_treatmentTourniquetLocal.sqf +++ /dev/null @@ -1,28 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal - * Apply a tourniquet to the patient, local callback. - * - * Arguments: - * 0: The patient - * 1: Item used classname - * 2: Body part - * - * Return Value: - * None - * - * Public: No - */ - -params ["_target", "_tourniquetItem", "_bodyPart"]; - -private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; - -// Place a tourniquet on the bodypart -private _tourniquets = GET_TOURNIQUETS(_target); - -_tourniquets set [_partIndex, CBA_missionTime]; - -_target setVariable [VAR_TOURNIQUET, _tourniquets, true]; - -[_target] call EFUNC(medical_status,updateWoundBloodLoss); diff --git a/addons/medical_treatment/functions/fnc_treatmentTourniquetRemove.sqf b/addons/medical_treatment/functions/fnc_treatmentTourniquetRemove.sqf deleted file mode 100644 index 0758713572..0000000000 --- a/addons/medical_treatment/functions/fnc_treatmentTourniquetRemove.sqf +++ /dev/null @@ -1,56 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal - * Action for removing the tourniquet on specified selection - * - * Arguments: - * 0: The medic - * 1: The patient - * 2: Body part - * - * Return Value: - * None - * - * Public: No - */ - -params ["_caller", "_target", "_bodyPart"]; -TRACE_3("params",_caller,_target,_bodyPart); - -// grab the required data -private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; -private _tourniquets = GET_TOURNIQUETS(_target); - -// Check if there is a tourniquet on this bodypart -if (_tourniquets select _partIndex == 0) exitWith { - [QEGVAR(common,displayTextStructured), [ELSTRING(medical_treatment,noTourniquetOnBodyPart), 1.5, _caller], [_caller]] call CBA_fnc_targetEvent; -}; - -// Removing the tourniquet -_tourniquets set [_partIndex, 0]; -_target setVariable [VAR_TOURNIQUET, _tourniquets, true]; - -[_target] call EFUNC(medical_status,updateWoundBloodLoss); - -// Adding the tourniquet item to the caller -[_caller, "ACE_tourniquet", true] call CBA_fnc_addItem; - -//Handle all injected medications now that blood is flowing -private _delayedMedications = _target getVariable [QEGVAR(medical,occludedMedications), []]; -private _updatedArray = false; -TRACE_2("meds",_partIndex,_delayedMedications); - -{ - _x params ["", "", "_medPartNum"]; - if (_partIndex == _medPartNum) then { - TRACE_1("delayed medication call after tourniquet removeal",_x); - [QGVAR(treatmentMedicationLocal), _x, _target] call CBA_fnc_targetEvent; - _delayedMedications set [_forEachIndex, -1]; - _updatedArray = true; - }; -} forEach _delayedMedications; - -if (_updatedArray) then { - _delayedMedications = _delayedMedications - [-1]; - _target setVariable [QEGVAR(medical,occludedMedications), _delayedMedications, true]; -}; diff --git a/addons/medical_treatment/functions/fnc_treatment_failure.sqf b/addons/medical_treatment/functions/fnc_treatment_failure.sqf deleted file mode 100644 index 8b3114cc66..0000000000 --- a/addons/medical_treatment/functions/fnc_treatment_failure.sqf +++ /dev/null @@ -1,56 +0,0 @@ -#include "script_component.hpp" -/* - * Author: KoffeinFlummi, Glowbal - * Callback when the treatment fails - * - * Arguments: - * 0: The medic - * 1: The patient - * 2: Body part - * 3: Treatment class name - * 4: Items available > - * - * Return Value: - * None - * - * Public: No - */ - -params ["_args"]; -_args params ["_caller", "_target", "_bodyPart", "_className", "_items", "_usersOfItems"]; - -// switch to end anim immediately -private _endInAnim = _caller getVariable QGVAR(endInAnim); - -if (!isNil "_endInAnim") then { - if (animationState _caller != _endInAnim) then { - [_caller, _endInAnim, 2] call EFUNC(common,doAnimation); - }; - _caller setVariable [QGVAR(endInAnim), nil]; - TRACE_1("abort",_endInAnim); -}; - -// reset sped up animations -[QEGVAR(common,setAnimSpeedCoef), [_caller, 1]] call CBA_fnc_globalEvent; - -{ - _x params ["_unit", "_item"]; - _unit addItem _item; -} forEach _usersOfItems; - -// Record specific callback -private _config = configFile >> QGVAR(Actions) >> _className; - -private _callback = getText (_config >> "callbackFailure"); - -if (isNil _callback) then { - _callback = compile _callback; -} else { - _callback = missionNamespace getVariable _callback; -}; - -if !(_callback isEqualType {}) then { - _callback = {TRACE_1("callback was NOT code",_callback)}; -}; - -_args call _callback; diff --git a/addons/medical_treatment/functions/fnc_treatment_success.sqf b/addons/medical_treatment/functions/fnc_treatment_success.sqf deleted file mode 100644 index 903e32e677..0000000000 --- a/addons/medical_treatment/functions/fnc_treatment_success.sqf +++ /dev/null @@ -1,71 +0,0 @@ -#include "script_component.hpp" -/* - * Author: KoffeinFlummi, Glowbal - * Callback when the treatment is completed - * - * Arguments: - * 0: The medic - * 1: The patient - * 2: Body part - * 3: Treatment class name - * 4: Items available > - * - * Return Value: - * None - * - * Public: No - */ - -params ["_args"]; -_args params ["_caller", "_target", "_bodyPart", "_className", "_items", "_usersOfItems"]; - -// switch to end anim immediately -private _endInAnim = _caller getVariable QGVAR(endInAnim); - -if (!isNil "_endInAnim") then { - if (animationState _caller != _endInAnim) then { - [_caller, _endInAnim, 2] call EFUNC(common,doAnimation); - }; - _caller setVariable [QGVAR(endInAnim), nil]; - TRACE_1("abort",_endInAnim); -}; - -// reset sped up animations -[QEGVAR(common,setAnimSpeedCoef), [_caller, 1]] call CBA_fnc_globalEvent; - -// Record specific callback -private _config = configFile >> QGVAR(Actions) >> _className; - -private _callback = getText (_config >> "callbackSuccess"); - -if (isNil _callback) then { - _callback = compile _callback; -} else { - _callback = missionNamespace getVariable _callback; -}; - -if !(_callback isEqualType {}) then { - _callback = {TRACE_1("callback was NOT code",_callback)}; -}; - -//Get current blood loose on limb (for "bloody" litter) -private _bloodLossOnBodyPart = 0; -private _partIndex = (ALL_BODY_PARTS find toLower _bodyPart) max 0; - -// Add all bleeding from wounds on selection -private _openWounds = _target getVariable [QEGVAR(medical,openWounds), []]; - -{ - _x params ["", "", "_bodyPartN", "_amountOf", "_percentageOpen"]; - - if (_bodyPartN isEqualTo _partIndex) then { - _bloodLossOnBodyPart = _bloodLossOnBodyPart + (_amountOf * _percentageOpen); - }; -} forEach _openWounds; -TRACE_1("advanced",_bloodLossOnBodyPart); - -_args call _callback; -_args pushBack _bloodLossOnBodyPart; -_args call FUNC(litterCreate); - -["ace_treatmentSucceded", [_caller, _target, _bodyPart, _className]] call CBA_fnc_localEvent; diff --git a/addons/medical_treatment/functions/fnc_unloadUnit.sqf b/addons/medical_treatment/functions/fnc_unloadUnit.sqf new file mode 100644 index 0000000000..6baeb005ca --- /dev/null +++ b/addons/medical_treatment/functions/fnc_unloadUnit.sqf @@ -0,0 +1,44 @@ +#include "script_component.hpp" +/* + * Author: Glowbal + * Unloads an unconscious or dead patient from their vehicle. + * + * Arguments: + * 0: Medic + * 1: Patient + * + * Return Value: + * None + * + * Example: + * [player, bob] call ace_medical_treatment_fnc_unloadUnit + * + * Public: No + */ + +params ["_medic", "_patient"]; +TRACE_2("unloadUnit",_medic,_patient); + +if (vehicle _patient == _patient) exitWith { + ERROR_1("Unit %1 is not in a vehicle",_patient); +}; + +if (_patient call EFUNC(common,isAwake)) exitWith { + ERROR_1("Unit %1 is awake",_patient); +}; + +["ace_unloadPersonEvent", [_patient, vehicle _patient, _medic], _patient] call CBA_fnc_targetEvent; + +[{ + params ["_unit", "_vehicle"]; + (alive _unit) && {alive _vehicle} && {(vehicle _unit) != _vehicle} +}, { + params ["_unit", "_vehicle"]; + TRACE_2("success",_unit,_vehicle); + private _patientName = [_unit, false, true] call EFUNC(common,getName); + private _vehicleName = getText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "displayName"); + [[LSTRING(UnloadedFrom), _patientName, _vehicleName], 3] call EFUNC(common,displayTextStructured); +}, [_patient, vehicle _patient], 3, { + params ["_unit", "_vehicle"]; + WARNING_3("unloadPerson failed to unload %1[local %2] -> %3 ",_unit,local _unit,_vehicle); +}] call CBA_fnc_waitUntilAndExecute; diff --git a/addons/medical_treatment/functions/fnc_useItem.sqf b/addons/medical_treatment/functions/fnc_useItem.sqf index 6977052209..a7484639da 100644 --- a/addons/medical_treatment/functions/fnc_useItem.sqf +++ b/addons/medical_treatment/functions/fnc_useItem.sqf @@ -1,45 +1,38 @@ #include "script_component.hpp" /* - * Author: Glowbal - * Use Equipment if any is available. Priority: 1) Medic, 2) Patient. If in vehicle: 3) Crew + * Author: Glowbal, mharis001 + * Uses one of the treatment items. Respects the priority defined by the allowSharedEquipment setting. * * Arguments: * 0: Medic * 1: Patient - * 2: Item + * 2: Items * - * ReturnValue: - * 0: success - * 1: Unit + * Return Value: + * User and Item + * + * Example: + * [player, cursorObject, ["bandage"]] call ace_medical_treatment_fnc_useItems * * Public: No */ -params ["_medic", "_patient", "_item"]; +params ["_medic", "_patient", "_items"]; -if (isNil QEGVAR(medical,setting_allowSharedEquipment)) then { - EGVAR(medical,setting_allowSharedEquipment) = true; -}; +scopeName "Main"; -if (EGVAR(medical,setting_allowSharedEquipment) && {[_patient, _item] call EFUNC(common,hasItem)}) exitWith { - ["ace_useItem", [_patient, _item], _patient] call CBA_fnc_targetEvent; - [true, _patient] -}; +private _useOrder = [[_patient, _medic], [_medic, _patient], [_medic]] select GVAR(allowSharedEquipment); -if ([_medic, _item] call EFUNC(common,hasItem)) exitWith { - ["ace_useItem", [_medic, _item], _medic] call CBA_fnc_targetEvent; - [true, _medic] -}; +{ + private _unit = _x; + private _unitItems = _x call EFUNC(common,uniqueItems); -private _return = [false, objNull]; - -if (vehicle _medic != _medic && {vehicle _medic call FUNC(isMedicalVehicle)}) then { { - if ([_medic, _x] call FUNC(canAccessMedicalEquipment) && {[_x, _item] call EFUNC(common,hasItem)}) exitWith { - ["ace_useItem", [_x, _item], _x] call CBA_fnc_targetEvent; - _return = [true, _x]; + if (_x in _unitItems) then { + _unit removeItem _x; + [_unit, _x] breakOut "Main"; }; - } forEach crew vehicle _medic; -}; + } forEach _items; +} forEach _useOrder; -_return +[objNull, ""] diff --git a/addons/medical_treatment/functions/fnc_useItems.sqf b/addons/medical_treatment/functions/fnc_useItems.sqf deleted file mode 100644 index 13ccf627b0..0000000000 --- a/addons/medical_treatment/functions/fnc_useItems.sqf +++ /dev/null @@ -1,50 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Glowbal - * Use Equipment items if any is available. Priority: 1) Medic, 2) Patient. If in vehicle: 3) Crew - * - * Arguments: - * 0: Medic - * 1: Patient - * 2: Items > - * - * Return Value: - * 0: success - * 1: Unit - * - * Example: - * [unit, patient, ["bandage"]] call ace_medical_treatment_fnc_useItems - * - * Public: No - */ - -#define HAS_USED_ITEM(itemUsedInfo) (itemUsedInfo select 0) -#define GET_ITEM_USED_BY(itemUsedInfo) (itemUsedInfo select 1) - -params ["_medic", "_patient", "_items"]; - -private _itemsUsedBy = []; - -{ - // handle a one of type use item - if (_x isEqualType []) then { - { - private _itemUsedInfo = [_medic, _patient, _x] call FUNC(useItem); - - if (HAS_USED_ITEM(_itemUsedInfo)) exitWith { - _itemsUsedBy pushBack [GET_ITEM_USED_BY(_itemUsedInfo), _x]; - }; - } forEach _x; - }; - - // handle required item - if (_x isEqualType "") then { - private _itemUsedInfo = [_medic, _patient, _x] call FUNC(useItem); - - if (HAS_USED_ITEM(_itemUsedInfo)) exitWith { - _itemsUsedBy pushBack [GET_ITEM_USED_BY(_itemUsedInfo), _x]; - }; - }; -} forEach _items; - -[count _items == count _itemsUsedBy, _itemsUsedBy]; diff --git a/addons/medical_treatment/initSettings.sqf b/addons/medical_treatment/initSettings.sqf index 6cd3f8c897..7e4eda5e98 100644 --- a/addons/medical_treatment/initSettings.sqf +++ b/addons/medical_treatment/initSettings.sqf @@ -1,206 +1,222 @@ -// CBA Settings [ADDON: ace_medical_treatment]: -private _categoryArray = [LELSTRING(medical,Category_DisplayName), LLSTRING(subCategory)]; - -// todo: the strings for all three advanced bandages/medication/diagnose settings are terribly ambigious - -[// todo: I don't like that wound reopening requires this setting to be enabled, they should be independent - QGVAR(advancedBandages), "CHECKBOX", - [LSTRING(advancedBandages_DisplayName), LSTRING(advancedBandages_Description)], - _categoryArray, - true, // default value - true, // isGlobal - {[QGVAR(advancedBandages), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart -] call CBA_settings_fnc_init; - -[// todo: this setting just disables some treatment options, remove? - QGVAR(advancedDiagnose), "CHECKBOX", - [LSTRING(advancedDiagnose_DisplayName), LSTRING(advancedDiagnose_Description)], - _categoryArray, - true, // default value - true, // isGlobal - {[QGVAR(advancedDiagnose), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart +// todo: this setting just disables some treatment options, remove? +[ + QGVAR(advancedDiagnose), + "CHECKBOX", + [LSTRING(AdvancedDiagnose_DisplayName), LSTRING(AdvancedDiagnose_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + true, + true ] call CBA_settings_fnc_init; [ - QGVAR(advancedMedication), "CHECKBOX", - [LSTRING(advancedMedication_DisplayName), LSTRING(advancedMedication_Description)], - _categoryArray, - true, // default value - true, // isGlobal - {[QGVAR(advancedMedication), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(advancedBandages), + "CHECKBOX", + [LSTRING(AdvancedBandages_DisplayName), LSTRING(AdvancedBandages_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + true, + true +] call CBA_settings_fnc_init; + +// todo: verify that this setting does not require a restart +// todo: this setting requires advanced bandages to be enabled, they should be independent +[ + QGVAR(woundReopening), + "CHECKBOX", + [LSTRING(WoundReopening_DisplayName), LSTRING(WoundReopening_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + true, + true ] call CBA_settings_fnc_init; [ - QGVAR(woundReopening), "CHECKBOX", - [LSTRING(woundReopening_DisplayName), LSTRING(woundReopening_Description)], - _categoryArray, - true, // default value - true, // isGlobal - {[QGVAR(woundReopening), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(clearTraumaAfterBandage), + "CHECKBOX", + [LSTRING(clearTraumaAfterBandage_DisplayName), LSTRING(clearTraumaAfterBandage_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + false, + true ] call CBA_settings_fnc_init; [ - QGVAR(allowSelfIV), "LIST", // This setting is list because we want number for treatment config - [LSTRING(allowSelfIV_DisplayName), LSTRING(allowSelfIV_Description)], - _categoryArray, - [[0,1],["No","Yes"],0], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(allowSelfIV), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(advancedMedication), + "CHECKBOX", + [LSTRING(AdvancedMedication_DisplayName), LSTRING(AdvancedMedication_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + true, + true ] call CBA_settings_fnc_init; -// Ported Settings: +// todo: should this setting differentiate between medical vehicles and facilities? [ - QEGVAR(medical,convertItems), "LIST", - [LSTRING(convertItems_DisplayName), LSTRING(convertItems_Description)], - _categoryArray, - [[0,1,2],[LELSTRING(common,Enabled),LLSTRING(convertItems_remove),LELSTRING(common,Disabled)],0], // [values, titles, defaultIndex] - true, // isGlobal - {[QEGVAR(medical,convertItems), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(locationsBoostTraining), + "CHECKBOX", + [LSTRING(LocationsBoostTraining_DisplayName), LSTRING(LocationsBoostTraining_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + false, + true ] call CBA_settings_fnc_init; [ - QEGVAR(medical,allowLitterCreation), "CHECKBOX", - [LSTRING(allowLitterCreation), LSTRING(allowLitterCreation_Description)], - _categoryArray, - true, // default value - true, // isGlobal - {[QEGVAR(medical,allowLitterCreation), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(allowSelfIV), + "LIST", + [LSTRING(AllowSelfIV_DisplayName), LSTRING(AllowSelfIV_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [[0, 1], [ELSTRING(common,No), ELSTRING(common,Yes)], 1], + true ] call CBA_settings_fnc_init; [ - QEGVAR(medical,CPRcreatesPulse), "CHECKBOX", - [LSTRING(CPRcreatesPulse), LSTRING(CPRcreatesPulse_Description)], - _categoryArray, - true, // default value - true, // isGlobal - {[QEGVAR(medical,CPRcreatesPulse), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(allowSharedEquipment), + "LIST", + [LSTRING(AllowSharedEquipment_DisplayName), LSTRING(AllowSharedEquipment_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [[0, 1, 2], [LSTRING(AllowSharedEquipment_PriorityPatient), LSTRING(AllowSharedEquipment_PriorityMedic), ELSTRING(common,No)], 0], + true ] call CBA_settings_fnc_init; [ - QEGVAR(medical,litterCleanUpDelay), "SLIDER", - [LSTRING(litterCleanUpDelay), LSTRING(litterCleanUpDelay_Description)], - _categoryArray, - [-1,5000,0,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QEGVAR(medical,litterCleanUpDelay), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(convertItems), + "LIST", + [LSTRING(ConvertItems_DisplayName), LSTRING(ConvertItems_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [[0, 1, 2], [ELSTRING(common,Enabled), LSTRING(ConvertItems_RemoveOnly), ELSTRING(common,Disabled)], 0], + true ] call CBA_settings_fnc_init; [ - QEGVAR(medical,litterSimulationDetail), "LIST", - [LSTRING(litterSimulationDetail), LSTRING(litterSimulationDetail_Description)], - _categoryArray, - [[0,1,2,3,4],["Off","Low","Medium","High","Ultra"],3], // [values, titles, defaultIndex] - true, // isGlobal - {[QEGVAR(medical,litterSimulationDetail), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(medicEpinephrine), + "LIST", + [LSTRING(MedicEpinephrine_DisplayName), LSTRING(MedicEpinephrine_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [[0, 1, 2], [LSTRING(Anyone), LSTRING(Medics), LSTRING(Doctors)], 0], + true ] call CBA_settings_fnc_init; [ - QEGVAR(medical,increaseTrainingInLocations), "CHECKBOX", - [LSTRING(increaseTrainingInLocations_DisplayName), LSTRING(increaseTrainingInLocations_Description)], - _categoryArray, - false, // default value - true, // isGlobal - {[QEGVAR(medical,increaseTrainingInLocations), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(locationEpinephrine), + "LIST", + [LSTRING(LocationEpinephrine_DisplayName), LSTRING(LocationEpinephrine_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [[0, 1, 2, 3, 4], [ELSTRING(common,Anywhere), ELSTRING(common,Vehicle), LSTRING(MedicalFacilities), LSTRING(VehiclesAndFacilities), ELSTRING(common,Disabled)], 0], + true ] call CBA_settings_fnc_init; [ - QEGVAR(medical,PAKTime), "SLIDER", - [LSTRING(PAKTime), LSTRING(PAKTime_Description)], - _categoryArray, - [-1,5000,0,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QEGVAR(medical,PAKTime), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(medicPAK), + "LIST", + [LSTRING(MedicPAK_DisplayName), LSTRING(MedicPAK_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [[0, 1, 2], [LSTRING(Anyone), LSTRING(Medics), LSTRING(Doctors)], 1], + true ] call CBA_settings_fnc_init; [ - QEGVAR(medical,medicSetting_Epi), "LIST", - [LSTRING(medicSetting_Epi_DisplayName), LSTRING(medicSetting_Epi_Description)], - _categoryArray, - [[0,1,2],["Anyone","Medics only","Doctors only"],0], // [values, titles, defaultIndex] - true, // isGlobal - {[QEGVAR(medical,medicSetting_Epi), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(locationPAK), + "LIST", + [LSTRING(LocationPAK_DisplayName), LSTRING(LocationPAK_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [[0, 1, 2, 3, 4], [ELSTRING(common,Anywhere), ELSTRING(common,Vehicle), LSTRING(MedicalFacilities), LSTRING(VehiclesAndFacilities), ELSTRING(common,Disabled)], 3], + true ] call CBA_settings_fnc_init; [ - QEGVAR(medical,medicSetting_PAK), "LIST", - [LSTRING(medicSetting_PAK_DisplayName), LSTRING(medicSetting_PAK_Description)], - _categoryArray, - [[0,1,2],["Anyone","Medics only","Doctors only"],0], // [values, titles, defaultIndex] - true, // isGlobal - {[QEGVAR(medical,medicSetting_PAK), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(consumePAK), + "LIST", + [LSTRING(ConsumePAK_DisplayName), LSTRING(ConsumePAK_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [[0, 1], [ELSTRING(common,No), ELSTRING(common,Yes)], 0], + true ] call CBA_settings_fnc_init; [ - QEGVAR(medical,medicSetting_SurgicalKit), "LIST", - [LSTRING(MedicalSettings_medicSetting_SurgicalKit_DisplayName), LSTRING(MedicalSettings_medicSetting_SurgicalKit_Description)], - _categoryArray, - [[0,1,2],["Anyone","Medics only","Doctors only"],0], // [values, titles, defaultIndex] - true, // isGlobal - {[QEGVAR(medical,medicSetting_SurgicalKit), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(timeCoefficientPAK), + "SLIDER", + [LSTRING(TimeCoefficientPAK_DisplayName), LSTRING(TimeCoefficientPAK_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [0, 5, 1, 1], + true ] call CBA_settings_fnc_init; [ - QEGVAR(medical,consumeItem_PAK), "LIST", - [LSTRING(MedicalSettings_consumeItem_PAK_DisplayName), LSTRING(MedicalSettings_consumeItem_PAK_Description)], - _categoryArray, - [[0,1],["No","Yes"],1], // [values, titles, defaultIndex] - true, // isGlobal - {[QEGVAR(medical,consumeItem_PAK), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(medicSurgicalKit), + "LIST", + [LSTRING(MedicSurgicalKit_DisplayName), LSTRING(MedicSurgicalKit_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [[0, 1, 2], [LSTRING(Anyone), LSTRING(Medics), LSTRING(Doctors)], 1], + true ] call CBA_settings_fnc_init; [ - QEGVAR(medical,consumeItem_SurgicalKit), "LIST", - [LSTRING(MedicalSettings_consumeItem_SurgicalKit_DisplayName), LSTRING(MedicalSettings_consumeItem_SurgicalKit_Description)], - _categoryArray, - [[0,1],["No","Yes"],1], // [values, titles, defaultIndex] - true, // isGlobal - {[QEGVAR(medical,consumeItem_SurgicalKit), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(locationSurgicalKit), + "LIST", + [LSTRING(LocationSurgicalKit_DisplayName), LSTRING(LocationSurgicalKit_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [[0, 1, 2, 3, 4], [ELSTRING(common,Anywhere), ELSTRING(common,Vehicle), LSTRING(MedicalFacilities), LSTRING(VehiclesAndFacilities), ELSTRING(common,Disabled)], 2], + true ] call CBA_settings_fnc_init; [ - QEGVAR(medical,useLocation_Epi), "LIST", - [LSTRING(MedicalSettings_useLocation_Epi_DisplayName), LSTRING(MedicalSettings_useLocation_Epi_Description)], - _categoryArray, - [[0,1,2,3,4],[LELSTRING(common,Anywhere), LELSTRING(common,Vehicle), LLSTRING(medicalFacility), LLSTRING(vehicleAndFacility), LELSTRING(common,Disabled)],0], // [values, titles, defaultIndex] - true, // isGlobal - {[QEGVAR(medical,useLocation_Epi), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(consumeSurgicalKit), + "LIST", + [LSTRING(ConsumeSurgicalKit_DisplayName), LSTRING(ConsumeSurgicalKit_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [[0, 1], [ELSTRING(common,No), ELSTRING(common,Yes)], 0], + true ] call CBA_settings_fnc_init; [ - QEGVAR(medical,useLocation_PAK), "LIST", - [LSTRING(MedicalSettings_useLocation_PAK_DisplayName), LSTRING(MedicalSettings_useLocation_PAK_Description)], - _categoryArray, - [[0,1,2,3,4],[LELSTRING(common,Anywhere), LELSTRING(common,Vehicle), LLSTRING(medicalFacility), LLSTRING(vehicleAndFacility), LELSTRING(common,Disabled)],0], // [values, titles, defaultIndex] - true, // isGlobal - {[QEGVAR(medical,useLocation_PAK), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(allowSelfStitch), + "LIST", + [LSTRING(AllowSelfStitch_DisplayName), LSTRING(AllowSelfStitch_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [[0, 1], [ELSTRING(common,No), ELSTRING(common,Yes)], 0], + true ] call CBA_settings_fnc_init; [ - QEGVAR(medical,useLocation_SurgicalKit), "LIST", - [LSTRING(MedicalSettings_useLocation_SurgicalKit_DisplayName), LSTRING(MedicalSettings_useLocation_SurgicalKit_Description)], - _categoryArray, - [[0,1,2,3,4],[LELSTRING(common,Anywhere), LELSTRING(common,Vehicle), LLSTRING(medicalFacility), LLSTRING(vehicleAndFacility), LELSTRING(common,Disabled)],0], // [values, titles, defaultIndex] - true, // isGlobal - {[QEGVAR(medical,useLocation_SurgicalKit), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(cprSuccessChance), + "SLIDER", + [LSTRING(cprSuccessChance_DisplayName), LSTRING(cprSuccessChance_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [0, 1, 0.4, 2], + true ] call CBA_settings_fnc_init; + +[ + QGVAR(allowLitterCreation), + "CHECKBOX", + [LSTRING(AllowLitterCreation_DisplayName), LSTRING(AllowLitterCreation_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Litter)], + true, + true +] call CBA_settings_fnc_init; + +[ + QGVAR(maxLitterObjects), + "LIST", + [LSTRING(MaxLitterObjects_DisplayName), LSTRING(MaxLitterObjects_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Litter)], + [[50, 100, 200, 300, 400, 500, 1000, 2000, 3000, 4000, 5000], [/* settings function will auto create names */], 5], + true +] call CBA_settings_fnc_init; + +[ + QGVAR(litterCleanupDelay), + "SLIDER", + [LSTRING(LitterCleanupDelay_DisplayName), LSTRING(LitterCleanupDelay_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Litter)], + [-1, 3600, 600, 0], + true +] call CBA_settings_fnc_init; + +[ + QGVAR(holsterRequired), + "LIST", + [LSTRING(HolsterRequired_DisplayName), LSTRING(HolsterRequired_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [[0, 1, 2, 3, 4], [ELSTRING(common,Disabled), LSTRING(HolsterRequired_Lowered), LSTRING(HolsterRequired_LoweredExam), LSTRING(HolsterRequired_Holstered), LSTRING(HolsterRequired_HolsteredExam)], 0], + true +] call CBA_settings_fnc_init; + + diff --git a/addons/medical_treatment/script_component.hpp b/addons/medical_treatment/script_component.hpp index 7f746cdcfe..bed5241f85 100644 --- a/addons/medical_treatment/script_component.hpp +++ b/addons/medical_treatment/script_component.hpp @@ -16,3 +16,35 @@ #include "\z\ace\addons\medical_engine\script_macros_medical.hpp" #include "\z\ace\addons\main\script_macros.hpp" + +// Returns a text config entry as compiled code or variable from missionNamespace +#define GET_FUNCTION(var,cfg) \ + private var = getText (cfg); \ + if (isNil var) then { \ + var = compile var; \ + } else { \ + var = missionNamespace getVariable var; \ + } + +// Returns a number config entry with default value of 0 +// If entry is a string, will get the variable from missionNamespace +#define GET_NUMBER_ENTRY(cfg) \ + if (isText (cfg)) then { \ + missionNamespace getVariable [getText (cfg), 0]; \ + } else { \ + getNumber (cfg); \ + } + +// Macros for checking if unit is in medical vehicle or facility +// Defined mostly to make location check in canTreat more readable +#define IN_MED_VEHICLE(unit) (unit call FUNC(isInMedicalVehicle)) +#define IN_MED_FACILITY(unit) (unit call FUNC(isInMedicalFacility)) + +#define TREATMENT_LOCATIONS_ALL 0 +#define TREATMENT_LOCATIONS_VEHICLES 1 +#define TREATMENT_LOCATIONS_FACILITIES 2 +#define TREATMENT_LOCATIONS_VEHICLES_AND_FACILITIES 3 +#define TREATMENT_LOCATIONS_NONE 4 + +#define LITTER_CLEANUP_CHECK_DELAY 30 +#define BODY_CLEANUP_CHECK_DELAY 20 diff --git a/addons/medical_treatment/stringtable.xml b/addons/medical_treatment/stringtable.xml index 75b9dffc8d..675e39f5ea 100644 --- a/addons/medical_treatment/stringtable.xml +++ b/addons/medical_treatment/stringtable.xml @@ -1,374 +1,450 @@ - - - Treatment - - - Advanced Bandages - - - Enable advanced bandages (required for wound reopening) - - - Advanced Diagnose - - - Enable advanced diagnose - - - Advanced Medication - - - Enable advanced medication - - - Locations boost training - Místa pro vylepšení zkušeností - Località aumentano addestramento - Örtliche Trainingssteigerung - Ubicación mejora entrenamiento. - Miejsca zwiększają wyszkolenie - Localização melhora treinamento - Le lieu améliore l'efficacité - Места ускоренного обучения - 衛生兵としての能力を与える場所 - 교육 증가 지역 - 受所在位置影响提升医疗能力 - 受所在位置影響提升醫療能力 - - - Boost medic rating in medical vehicles or near medical facilities [untrained becomes medic, medic becomes doctor] - Zlepšit zkušenosti zdravotníka v medickém vozidle nebo poblíž zdravotního zařízení [nezkušení se stane zdravotníkem, zdravotník se stane doktorem] - Aumenta il rating medico in veicoli medici o vicino strutture mediche [non addestrato diventa medico, medico diventa dottore] - Steigert die medizinische Einstufung eines Soldaten in Sanitätsfarhzeugen oder in der Nähe von Sanitätseinrichtungen [untrainiert wird zu Sanitäter, Sanitäter zu Doktor] - Mejora el entrenamiento médico dentro de vehículos médicos o cerca de instalaciones médicas (no entrenados se convierten en médicos, médicos se convierten en doctores) - Zwiększa poziom wyszkolenia medyków wewnątrz pojazdów medycznych lub w pobliżu budynków medycznych [niedoświadczony zostaje medykiem, medyk zostaje doktorem] - Aumenta a classificação do médico dentro de veículos médicos ou perto de instalações médicas [sem treinamento vira médico, médico vira doutor] - Améliore l'efficacité des soins dans les véhicules ou structures de soins [non formés deviennent médecins, médecins deviennent docteurs] - Улучшает медицинскую подготовку в мед. транспорте и около мед. строений [нетренированные становятся медиками, медики становятся врачами] - 医療車両や医療施設の近くは衛生兵としての能力を与える場所となり、衛生兵の訓練を受けていないのに衛生兵としてなる (未訓練は衛生兵に、衛生兵は医師に) - 의무병의 수준이 주변의 차량이나 의료시설에 따라 증가합니다. [비교육자가 의무병이되고, 의무병이 의사가 됩니다] - 当人员在医疗载具或是医护设施旁进行医疗时, 该员医疗能力将会有所提升 (未受训人员提升为医疗兵, 医疗兵提升为军医) - 當人員在醫療載具或是醫護設施旁進行醫療時, 該員醫療能力將會有所提升 (未受訓人員提升為醫療兵, 醫療兵提升為軍醫) - - - Self IV Transfusion - - - Allows using IV Transfusions on yourself - - - CPR creates pulse - HLW erzeugt einen Puls - - - CPR will create a pulse for the patient while performing - HLW erzeugt während der Behandlung beim Patienten einen Puls - - - Enable Advanced wounds - Усложненные раны - Aktywuj zaawansowane rany - Activa heridas avanzadas - Aktiviere erweiterte Wunden - Povolit pokročilé zranění - Ativar ferimentos avançados - Activer les plaies compliquées - Komplex sebek engedélyezése - Abilita ferite Avanzate - アドバンスドな傷を有効化 - 고급 부상 활성화 - 启用进阶伤口系统 - 啟用進階傷口系統 - - - Allow reopening of bandaged wounds? - Будут ли открываться уже перевязанные раны? - Pozwól na otwieranie się zabandażowanych ran? - Permitir la reapertura de las heridas vendadas? - Erlaube das Öffnen von bandagierten Wunden? - Umožnit znovuotevření zavázané rány? - Permitr reabertura de ferimentos enfaixados? - Les plaies peuvent se rouvrir - Visszanyílhatnak a bekötözött sebek? - Permetti la riapertura di ferite bendate? - 包帯で巻かれた傷を再び開くようにしますか? - 붕대가 풀리는것을 활성화합니까? - 启用进阶伤口系统会使已被包扎的伤口有机率裂开 - 啟用進階傷口系統會使已被包紮的傷口有機率裂開 - - - - - Allow Epinephrine - Erlaube Epiniphrin - Permitir Epinefrina - Ograniczenia adrenaliny - Activer l'épinéphrine - Permette epinefrina - Povolit adrenalin - Permitir Epinefrina - Разрешить Адреналин - アドレナリンの許可 - 에피네프린 활성화 - 允许使用肾上腺素 - 允許使用腎上腺素 - - - Who can use Epinephrine? - - - Allow PAK - Использование аптечки - Ustawienie apteczek osobistych - Permitir EPA - Erlaube Erste-Hilfe-Set - Povolit osobní lékárničky (PAK) - Permitir Kit de Primeiros Socorros - Activer la trousse sanitaire - Elsősegélycsomag engedélyezése - Consenti Kit di Pronto Soccorso - 応急処置キットの許可 - 개인응급키트 활성화 - 允许使用个人急救包 - 允許使用個人急救包 - - - Who can use the PAK for full heal? - Кому разрешено выполнять полное лечение с помощью аптечки? - Kto może skorzystać z apteczki osobistej w celu pełnego uleczenia? - ¿Quién puede utilizar el EPA para una cura completa? - Wer kann das Erste-Hilfe-Set für eine Endheilung verwenden? - Kdo může použít osobní lékárničku pro plné vyléčení? - Quem pode usar o KPS para cura completa? - Qui peut utilier la trousse sanitaire pour des soins complets? - Ki használhatja az elsősegélycsomagot teljes gyógyításra? - Chi può usare il KPS per cura completa? - 完全に回復できるよう誰しもが応急処置キットを使えるようにしますか? - 완전한 체력회복을 위해 어느 인원이 개인응급키트을 쓸 수 있습니까? (기본 의료 전용) - 谁能够使用个人急救包来达到完整医疗? - 誰能夠使用個人急救包來達到完整醫療? - - - Anyone - Кем угодно - Wszyscy - Nadie - Jeder - Kdokoliv - Qualquer um - Tous - Akárki - Chiunque - だれでも - 모두 - 任何人 - 任何人 - - - Medics only - Только медиками - Tylko medycy - Solo médicos - Nur Sanitäter - Pouze zdravotník - Somente médicos - Infirmiers uniquement - Csak orvosok - Solo medici - 衛生兵のみ - 의무병만 - 只限医疗兵 - 只限醫療兵 - - - Doctors only - Только врачами - Tylko doktorzy - Solo doctores - Nur Ärzte - Pouze doktor - Somente doutores - Médecins uniquement - Csak doktorok - Solo dottori - 医師のみ - 오직 의사만 - 只限军医 - 只限軍醫 - - - Medical facility - В госпитале - Budynki medyczne - Centro médico - Medizinische Einrichtungen - Zdravotnické zařízení - Instalação médica - Dans les structures sanitaires - Orvosi létesítmény - Strutture mediche - 医療施設でのみ - 의료시설 - 医疗设施 - 醫療設施 - - - Vehicles & facility - В транспорте и госпитале - Pojazdy i budynki medyczne - Vehículos y centros - Fahrzeuge & Einrichtungen - Vozidla a zařízení - Veículos e instalações - Dans les véhicules et les structures sanitaires - Járművek & létesítmény - Veicoli e Strutture - 車両 & 施設 - 차량 및 시설 - 医疗载具 & 医疗设施 - 醫療載具 & 醫療設施 - - - Remove PAK on use - Удалять аптечки после использования - Usuń apteczkę po użyciu - Eliminar EPA después del uso - Entf. Erste-Hilfe-Set bei Verwendung - Odebrat osobní lékárničku po použití - Remover o KPS depois do uso - Utilisation unique de la trousse sanitaire - Elsősegélycsomag eltávolítása használatkor - Rimuovi Kit Pronto Soccorso dopo l'uso - 応急処置キットの削除 - 개인응급키트 사용후 사라짐 - 在使用后删除个人急救包 - 在使用後刪除個人急救包 - - - Should PAK be removed on usage? - Нужно ли удалять аптечки после использования? - Czy apteczka osobista powinna zniknąć z ekwipunku po jej użyciu? - El EPA será eliminado después de usarlo - Sollen Erste-Hilfe-Sets bei Verwendung entfernt werden? - Má se osobní lékárnička odstranit po použití? - Deve o KPS ser removido depois do uso? - La trousse sanitaire doit être consommée à l'utilisation? - Eltávolítódjon az elsősegélycsomag használatkor? - Il Kit Pronto Soccorso dev'essere rimosso dopo l'utilizzo? - 応急処置キットを使うと削除しますか? - 개인응급키트를 사용하고 나서 제거합니까? - 要在使用后删除个人急救包吗? - 要在使用後刪除個人急救包嗎? - - - Locations Epinephrine - Orte für Epiniphrin - Ubicaciones epinefrina - Ograniczenia adrenaliny - Utilisation de l'épinéphrine - Ubicazione epinefrina - Oblast k použití adrenalinu - Localizações de Epinefrina - Место использования адреналина - アドレナリンをつかう場所 - 에피네프린 사용 장소 - 肾上腺素使用地点 - 腎上腺素使用地點 - - - Where can the Epinephrine be used? - - - How long should PAK take to apply? - - - How long should PAK take to apply? Use 0 for default (based on damage) - - - - - Enable Litter - Включить мусор - Aktywuj odpadki - Activar restos médicos - Abfälle aktivieren - Povolit odpadky - Ativar lixo médico - Activer les détritus - Szemét engedélyezése - Abilita Barella - 医療廃棄物の表示を有効化 - - - Enable litter being created upon treatment - Включить появление мусора после лечения - Twórz odpadki medyczne podczas leczenia - Activar los restos médicos que se crean en el tratamiento - Aktiviere Abfälle, wenn eine Behandlung durchgeführt wurde - Vytváří odpad zdravotnického materiálu pří léčení - Ativar lixo ser criado após tratamento - Activer la création de détrimus au début des traitements - Engedélyezi a szemét keletkezését ellátáskor - Abilita la creazione della barella dopo trattamento - 治療を始めると、医療廃棄物の作成を有効化する - - - Litter Simulation Detail - Detale zużytych medykamentów - Detalle de simulación de basura - Количество мусора от медицины - Dettagli Simulazione Rifiuti - Niveau de simulation des détritus - Abfall-Detaillevel - Hulladékszimuláció részletessége - Detalhe da simulação de sujeira - Počet zobrazených předmětů po použití zdravotnického materiálu - 医療廃棄物を再現する詳細度 - - - Litter simulation detail level sets the number of litter items which will be locally spawned in the client. Excessive amounts in local areas could cause FPS lag, so this is a client only setting. - Opcja ta ustawia liczbę zużytych medykamentów, jakie pojawiają się lokalnie wokół gracza. Ich zbyt duża ilość może spowodować spadki FPS, dlatego jest to ustawienie tylko po stronie klienta. - Detalle simulación de basura establece el número de artículos de basura que se generan a nivel local en el cliente. Las cantidades excesivas en áreas locales podrían causar caída de rendimiento, así que esto es un ajuste de cliente únicamente. - Устанавливает количество мусора, который появляется после использования мед. препаратов. Большое количество мусора может уменьшить производительность, поэтому данная настройка локальна для клиента. - Il numero di rifiuti che verranno creati localmente. La creazione di troppi rifiuti in aree locali potrebbe causare lag e calo di FPS. Questo è un settaggio lato client. - Le niveau de simulation des détritus règle la quantité de déchets qui vont être créés localement chez le client. Des quantitées excessive chez certains clients peuvent causer des chutes de FPS, c'est donc une option client uniquement. - Die Einstellung für das Abfall-Detaillevel stellt die Menge des lokal angezeigten medizinischen Abfalls ein. Zuviel Abfall kann FPS-Einbrüche erzeugen, weswegen diese Einstellung nur clientseitig ist. - A hulladékszimuláció részletessége megszabja a kliens által megjelenített hulladékobjektumok mennyiségét. Súlyos mennyiségek izolált területeken alacsony FPS-t okozhatnak, így ez egy kliensoldali beállítás. - O nível de detalhe de sujeira determina o número de itens que irão aparecer no cliente. Quantidades excessivas em áreas locais podem aumentar o lag do FPS, então esta é uma opção somente para o cliente. - Počet zobrazených předmětů po použití zdravotnického materiálu ovlivňuje počet objektů, které budou zobrazeny klientovi v místě použití zdravotnického materiálu. Vyšší množství objektů může způsobovat poklesy FPS a proto je toto nastavení čistě na klientovi. - 医療廃棄物再現度は各クライアントでローカルに作成される、医療廃棄物への詳細度を決定できます。ローカルで多くのアイテムがあると FPS の低下を引き起こすため、クライアント側のみの設定です。 - - - Life time of litter objects - Время удаления мусора - Długość życia odpadków - Tiempo de vida de los restos médicos - Dauer des angezeigten Abfalls - Životnost pro odpadky - Tempo de vida dos objetos do lixo - Durée d'affichage des détritus - Szemétobjektumok élettartama - Tempo di vita delle barelle - 医療廃棄物の作成限界数を設定 - - - How long should litter objects stay? In seconds. -1 is forever. - Как долго мусор будет оставаться на земле? В секундах. -1 означает бесконечное время. - Ile czasu musi upłynąć, aby odpadki zaczęły znikać? W sekundach. -1 dla nieskończoności. - ¿Por cuánto tiempo deben permanecer los restos médicos? En segundos. -1 es para siempre. - Wie lange sollen Abfälle am Boden liegen (in Sekunden)? -1 ist für immer. - Za jak dlouho začnou odpadky mizet? V sekundách. -1 navždy. - Quanto tempo os objetos do lixo devem ficar? Em segundos. -1 é para sempre. - Combien de temps doivent rester affiché les détritus? En secondes. -1 pour tout le temps - Milyen sokáig legyenek jelen a szemétobjektumok (másodpercben)? A -1 végtelen időt jelent. - Per quanto devono restare le barelle? In secondi. -1 è permanente - 医療廃棄物オブジェクトが表示されつづける時間を設定しますか?-1 は永遠です。 - - - + + Treatment + Behandlung + 治療 + Лечение + Traitement + Tratamento + + + Litter + 廃棄物 + Détritus + Медицинский мусор + Lixo + + + Advanced Diagnose + Erweiterte Diagnose + アドバンスド診断 + Расширенная Диагностика + Diagnostic avancé + Diagnóstico Avançado + + + Enables the Check Pulse, Check Blood Pressure, and Check Response treatment actions instead of the generic Diagnose action.\nWhen disabled, the CPR action will only be shown when performing CPR is appropriate.\nThe actions this setting enables are needed to determine whether a person is unconscious or in cardiac arrest. + 有効化すると通常の診断動作に代わり、心拍や血圧測定、反応を確認できます。 + Permet un diagnostic avancé, en permettant la vérification du pouls, de la pression sanguine, ainsi que la réponse du patient aux traitements. + Включает действия «Проверить пульс», «Проверить давление» и «Проверить реакцию» вместо общего действия «Диагностика». + Ativa as opções de Verificar Pulso, Verificar Pressão Sanguínea e Verificar Resposta, ao invés do diagnóstico geral. + + + Advanced Bandages + Erweiterte Bandagen + アドバンスド包帯 + Расширенная Перевязка + Pansements avancés + Ataduras Avançadas + + + Enables treatment actions for different bandage types instead of the generic Bandage action. + 有効化すると通常の包帯動作に代わり、様々な種類がある包帯で治療ができます。 + 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. + + + Wound Reopening + 創傷再開放 + Réouverture des plaies + Повторное открытие ран + Reabrir Feridas + + + Enables the reopening of bandaged wounds. Requires Advanced Bandages to be enabled. + 有効化すると治療をした創傷を再開放します。アドバンスド包帯を有効化している必要があります。 + Permet la réouverture des plaies pansées.\nNécessite que l'option "pansements avancés" soit activée. + Разрешает повторное открытие перевязанных ран. Требуются опция «Расширенная Перевязка». + Permite que ferimentos atados possam reabrir. Requer Ataduras Avançadas para funcionar. + + + Advanced Medication + Erweiterte Medikamente + アドバンスド医薬品 + Расширенные Лекарства + Médication avancée + Medicação Avançada + + + Enables extended, more in-depth medication handling. Also, enables the use of Adenosine and Atropine. + Устанавливает расширенное использование лекарств + 有効化するともっと多くの多様な機能を持つ医薬品を使えます。また、アデノシンとアトロピンが利用可能になります。 + Permet une manipulation étendue et plus appronfondie des médicaments.\nEn outre, permet l'utilisation d'adénosine et d'atropine. + Ativa a manipulação avançada de medicações. Também permite o uso de Adenosina e Atropina. + + + Locations Boost Training + Místa pro vylepšení zkušeností + Località aumentano addestramento + Örtliche Trainingssteigerung + Ubicación mejora entrenamiento. + Miejsca zwiększają wyszkolenie + Localização melhora treinamento + Le lieu améliore l'efficacité + Места ускоренного обучения + 衛生能力の上昇位置 + 교육 증가 지역 + 受所在位置影响提升医疗能力 + 受所在位置影響提升醫療能力 + + + Boost medical training when in medical vehicles or facilities. Untrained becomes medic, medic becomes doctor. + 衛生車両か施設では衛生能力を上昇します。未訓練では衛生兵に、衛生兵では医師になります。 + Améliore les compétences médicales des unités en fonction du lieu où elles se trouvent ; notamment dans des véhicules ou des installations sanitaires.\nUn soldat non formé devient infirmier, un infirmier devient médecin. + Увеличивает уровень медподготовки при нахождении в медицинской технике или госпитале. Неподготовленный становится Медиком, Медик становится Доктором. + 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. + + + Self IV Transfusion + Eigennutzung von Bluttransfusionen + Внутривенное переливание на себе + 自己 IV 輸血 + Autotransfusion d'IV + Autotransfusão de IV + + + Enables the use of IV Transfusions on oneself. + Erlaube Bluttransfusionen an sich selbst zu benutzen + Позволяет использовать внутривенные переливания на себе + 自らに対して IV 輸血を可能にします。 + Permet de poser des IV sur soi-même. + Permite utilizar bolsas de IV para transfusão em si mesmo + + + Allow Shared Equipment + 装備共有を許可 + Autoriser partage matériel + Разрешить общие медикаменты + Permitir Compartilhar Itens Médicos + + + Controls whether medical equipment can be shared between the patient and the medic. + 患者と衛生兵との間で医療品の共有をするかどうかを決定します。 + Détermine si le matériel médical du médecin et du patient est partagé et mis en commun. + Контролирует, можно ли разделить медикаменты между пациентом и врачом. + Controla se um item médico pode ser compartilhado entre médico e paciente. + + + Patient's Equipment First + 患者の装備を先に使用 + L'équipement du patient d'abord + Сначала медикаменты пациента + Usar do Paciente Primeiro + + + Medic's Equipment First + 衛生兵の装備を先に使用 + L'équipement du médecin d'abord + Сначала медикаменты врача + Usar do Médico Primeiro + + + Allow Epinephrine + Erlaube Epiniphrin + Permitir Epinefrina + Ograniczenia adrenaliny + Activer l'épinéphrine + Permette epinefrina + Povolit adrenalin + Permitir Epinefrina + Разрешить Адреналин + アドレナリンの許可 + 에피네프린 활성화 + 允许使用肾上腺素 + 允許使用腎上腺素 + + + Training level required to use Epinephrine. + アドレナリンの使用に訓練レベルを必要とさせます。 + Une qualification médicale est requise pour pouvoir utiliser l'épinéphrine. + Уровень подготовки, необходимый для использования Адреналина. + É necessária uma qualificação médica para usar epinefrina. + + + Locations Epinephrine + Orte für Epiniphrin + Ubicaciones epinefrina + Ograniczenia adrenaliny + Lieux épinéphrine + Ubicazione epinefrina + Oblast k použití adrenalinu + Localizações de Epinefrina + Места использования Адреналина + アドレナリンの使用可能場所 + 에피네프린 사용 장소 + 肾上腺素使用地点 + 腎上腺素使用地點 + + + Controls where Epinephrine can be used. + アドレナリンが使える場所を決定します。 + Définit où l'épinéphrine peut être utilisée. + Контролирует, где можно использовать Адреналин. + Controla onde Epinefrina pode ser utilizada. + + + Allow PAK + Использование Аптечки + Ustawienie apteczek osobistych + Permitir EPA + Erlaube Erste-Hilfe-Set + Povolit osobní lékárničky (PAK) + Permitir Kit de Primeiros Socorros (KPS) + Autoriser trousse sanitaire + Elsősegélycsomag engedélyezése + Consenti Kit di Pronto Soccorso + 応急処置キットの許可 + 개인응급키트 활성화 + 允许使用个人急救包 + 允許使用個人急救包 + + + Training level required to use a PAK. + 応急処置キットの使用に訓練レベルを必要とさせます。 + Une qualification médicale est requise pour pouvoir utiliser la trousse sanitaire. + Уровень подготовки, необходимый для использования Аптечки. + É necessária uma qualificação médica para usar KPS + + + Locations PAK + Места использования Аптечки + Ograniczenie apteczek osobistych + Ubicaciones del EPA + Orte für Erste-Hilfe-Set + Oblast k použití PAK + Localizações do KPS + Lieux trousse sanitaire + Elsősegélycsomag helyek + Locazioni Kit Pronto Soccorso + 応急処置キットの使用可能場所 + 개인응급키트 사용 장소 + 个人急救包使用地点 + 個人急救包使用地點 + + + Controls where a PAK can be used. + 応急処置キットが使える場所を決定します。 + Définit où la trousse sanitaire peut être utilisée. + Контролирует, где можно использовать Аптечку. + Controla onde o KPS pode ser utilizado. + + + Consume PAK + 応急処置キットの消費 + Trousse sanitaire consommable + Израсходовать Аптечку + KPS Descartável + + + Controls whether a PAK should be consumed after use. + 応急処置キットの使用後に消費するかどうかを決定します。 + Définit si la trousse sanitaire doit être à usage unique. + Контролирует, следует ли израсходовать Аптечку после использования. + Controla se o KPS deve ser descartado/consumido após o uso. + + + Time Coefficient PAK + 応急処置キットの時間係数 + Coef. temps trousse sanitaire + Контролирует, следует ли израсходовать Аптечку после использования. + Coeficiente de Tempo do KPS + + + 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 秒間で、この係数と体全体に負ったダメージによって決まります。 + 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. + + + Allow Surgical Kit + 縫合キットを許可 + Autoriser trousse chirurgicale + Разрешить Хирургический набор + Permitir Kit Cirúrgico + + + Training level required to use a Surgical Kit. + 縫合キットの使用に訓練レベルを必要とさせます。 + Une qualification médicale est requise pour pouvoir utiliser une trousse chirurgicale. + Уровень медицинской подготовки, необходимый для использования Хирургического набора. + É necessária uma qualificação médica para usar Kit Cirúrgico + + + Locations Surgical Kit + 縫合キットの使用可能場所 + Lieux trousse chirurgicale + Места использования Хирургического набора + Locais para Kit Cirúrgico + + + Controls where a Surgical Kit can be used. + 縫合キットが使える場所を決定します。 + Définit où la trousse chirurgicale peut être utilisée. + Контролирует, где можно использовать Хирургический набор + Controle onde o Kit Cirúrgico pode ser utilizado. + + + Consume Surgical Kit + 縫合キットの消費 + Trousse chirurgicale consommable + Израсходовать Хирургический набор + Kit Cirúrgico Consumível + + + Controls whether a Surgical Kit should be consumed after use. + 縫合キットの使用後に消費するかどうかを決定します。 + Définit si la trousse chirurgicale doit être à usage unique. + Контролирует, следует ли израсходовать Хирургический набор после использования. + Controla se o Kit Cirúrgico deve ser descartado/consumido após o uso. + + + Self Stitching + Suturer soi-même + Auto-Cirurgia + + + 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. + + + Convert Vanilla Items + Standard Arma-Equipment in ACE-Items umwandeln + Преобразовывать ванильные медикаменты + 標準アイテムの変換 + Convertir objets Vanilla + Converter itens vanilla + + + 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 医療アイテムへ変換、削除、そのままにするかを決定します。 + 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. + + + Remove Only + 削除 + Retirer uniquement + Удалять + Apenas Remover + + + Enable Litter + Включить мусор + Aktywuj odpadki + Activar restos médicos + Abfälle aktivieren + Povolit odpadky + Permitir Lixo Médico + Activer les détritus + Szemét engedélyezése + Abilita Barella + 廃棄物の有効化 + + + Enables the creation of litter upon treatment. + 治療後に廃棄物の生成を有効化します。 + Permet de laisser des détritus (emballages, pansements usagés...) suite à un traitement. + Разрешает создание медицинского мусора при лечении. + Permite a criação de lixo médico durante o tratamento. + + + Max Litter Objects + 最大廃棄物数 + Nombre maximum détritus + Макс. кол-во мусора + Máximo de Objetos de Lixo + + + Sets the maximum number of litter objects which can be spawned, excessive amounts can cause FPS lag. + 生成される最大廃棄物数を設定できます。極端に増やすと FPS ラグを引き起こします。 + Définit le nombre maximal de détritus pouvant être affichés.\nUne quantité excessive peut engendrer une baisse de FPS. + Устанавливает максимальное количество создаваемых объектов мусора. Чрезмерное значение может вызвать задержку FPS. + Define o limite máximo de objetos de lixo que podem ser criados, quantidade excessivas podem causar lag de FPS. + + + Litter Lifetime + 廃棄物寿命 + Durée d'affichage détritus + Время жизни мусора + Duração de Lixo + + + Controls the lifetime of litter objects, in seconds. -1 is forever. + 廃棄物の寿命を秒で決定できます。-1 で永遠です。 + Définit la durée d'affichage des détritus. + Управляет временем жизни объектов мусора в секундах. -1 означает Навсегда. + Controla o tempo de vida de objetos de lixo criados em segundos. -1 é para sempre. + + + Anyone + Кем угодно + Wszyscy + Nadie + Jeder + Kdokoliv + Qualquer um + Tout le monde + Akárki + Chiunque + だれでも + 모두 + 任何人 + 任何人 + + + Medics + 衛生兵 + Infirmiers + Медики + Médicos + + + Doctors + 医師 + Médecins + Доктора + Doutores + + + Medical Facilities + 医療施設 + Installations médicales + Госпитали + Instalações Médicas + + + Vehicles & Facilities + 車両 & 施設 + Véhicules & installations médicales + Техника и госпитали + Veículos e Instalações Médicas + + + Holster Required + + + Controls whether weapons must be holstered / lowered in order to perform medical actions.\nExcept Exam - Allows examination actions (checking pulse, blood pressure, response) at all times regardless of Holster Required setting. + + + Lowered or Holstered + + + Lowered or Holstered (Except Exam) + + + Holstered only + + + Holstered only (Except Exam) + + [ACE] Medical Supply Crate (Basic) [ACE] Ящик с медикаментами (базовая медицина) [ACE] Skrzynka z zapasami medycznymi (podstawowa) @@ -384,7 +460,7 @@ [ACE] 医疗补给箱(基本) [ACE] 醫療補給箱(基本) - + [ACE] Medical Supply Crate (Advanced) [ACE] Ящик с медикаментами (усложн. медицина) [ACE] Skrzynka z zapasami medycznymi (zaawansowana) @@ -400,7 +476,7 @@ [ACE] 医疗补给箱(进阶) [ACE] 醫療補給箱(進階) - + 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. @@ -414,22 +490,22 @@ 是否使该载具为医疗载具? 是否使該載具為醫療載具? - + Medical training Wyszkolenie medyczne Addestramento Medico Sanitätsausbildung Entrenamiento médico - Entraînement médical + Qualification médicale Lékařský výcvik Treino médico Медицинская подготовка - 治療の訓練 + 衛生訓練 의료 훈련 医疗训练 醫療訓練 - + Is Medic Является медиком Klasa medyczna @@ -440,18 +516,18 @@ Est infirmier Orvos-e E' Medico - 衛生兵として + 衛生兵に 의무병 是医疗兵 是醫療兵 - + This module allows you to assign the medic class to selected units. Moduł ten pozwala przypisać klasę medyczną wybranym jednostkom. Dieses Modul legt fest, welche Einheiten Sanitäter sind. Tento modul určuje, která jednotka je zdravotník. Este módulo determina qual unidade é um paramédico. - Ce module permet d'assigner la classe médicale à une unité sélectionnée + Ce module vous permet d'assigner une classe medicale aux unités sélectionnées. 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. @@ -461,7 +537,7 @@ 本模块可让被同步的单位成为医疗兵 本模塊可讓被同步的單位成為醫療兵 - + None Нет Żadna @@ -469,7 +545,7 @@ Keine Žádný Nada - Aucun + Aucune Nincs Nessuno なし @@ -477,8 +553,8 @@ - - Regular medic + + Regular Medic Обычный медик Zwykły medyk Médico regular @@ -493,7 +569,7 @@ 普通医疗兵 普通醫療兵 - + Is Medical Vehicle Является медицинским транспортом Jest pojazdem medycznym @@ -501,15 +577,15 @@ Ist medizinisches Fahrzeug Zdravotnické vozidlo É um veículo médico - Véhicule médical + Véhicule sanitaire Orvosi jármű-e E' Veicolo Medico - 医療車両として + 医療車両に 의료 차량 是医疗载具 是醫療載具 - + Is Medical Facility Является госпиталем Jest budynkiem medycznym @@ -517,15 +593,15 @@ Ist eine medizinische Einrichtung Zdravotnické zařízení É uma instalação médica - Est une installation médical + Est une installation médicale Orvosi létesítmény-e E' Struttura Medica - 医療施設として + 医療施設に 의료시설 是医疗设施 是醫療設施 - + Registers an object as a medical facility Определяет объект в качестве госпиталя Przypisuje danemu obiektowi status budynku medycznego @@ -533,7 +609,7 @@ Definiert ein Objekt als medizinische Einrichtung Registruje objekt jako zdravotnické zařízení Registra um objeto como instalacão médica - Enregistrer un objet comme une installation médical + Définit un objet comme étant une installation médicale. Egy objektum orvosi létesítményként való regisztrálása Registra un oggetto come struttura medica オブジェクトを医療施設として割り当てる @@ -541,7 +617,7 @@ 指定一个物件作为医疗设施 指定一個物件作為醫療設施 - + Doctor (Only Advanced Medics) Врач (только усложн.) Doktor (tylko zaawansowani medycy) @@ -549,7 +625,7 @@ Arzt (Nur erweitertes Sanitätssystem) Doktor (Pouze pokročilý zdravotníci) Doutor (Somente médicos avançados) - Médecin (traitements avancés uniquement) + Médecin (uniquement en médecine avancée) Doktor (csak fejlett orvosok) Dottore (Solo Medici Avanzati) 医師 (アドバンスド医療のみ) @@ -557,7 +633,7 @@ 军医 (只限进阶医疗系统) 軍醫 (只限進階醫療系統) - + Doctor Врач Doktor @@ -573,12 +649,12 @@ 军医 軍醫 - + Bandage (Basic) Bandage (Einfach) Повязка (обычная) Vendaje (Básico) - Pansement adhésif + Pansement individuel Bandaż (jałowy) Obvaz (Standartní) Kötszer (Általános) @@ -589,7 +665,7 @@ 基础绷带 基礎繃帶 - + Used to cover a wound Для перевязки ран Utilizado para cubrir una herida @@ -600,12 +676,12 @@ Usato per coprire una ferita Usado para cobrir um ferimento Slouží k překrytí poranění - 傷口をおおう + 傷口を覆います 상처를 덮을때 씁니다 用于覆盖伤口 用於覆蓋傷口 - + A dressing, that is a particular material used to cover a wound, which is applied over the wound once bleeding has been stemmed. Ein Verband, der aus einem besonderen Material besteht um die Wunde zu schützen, nachdem die Blutung gestoppt wurde. Повязка, накладываемая поверх раны после остановки кровотечения. @@ -616,17 +692,17 @@ Una benda apposita, utilizzata per coprire una ferita, la quale viene applicata su di essa 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í. - 緊急圧迫包帯は、傷口を血液凝固剤でおおうようにできていて、つかうと出血の原因を取りさります。 + 傷口を血液凝固剤で塞ぐようにできていて、使うと出血の原因を取りさります。 드레싱, 출혈을 막고서 상처를 덮기위해 쓰는 물건입니다. 用于覆盖伤口以防止出血, 透过敷料的止血剂来让出血慢慢停止 用於覆蓋傷口以防止出血, 透過敷料的止血劑來讓出血慢慢停止 - + Packing Bandage Mullbinde Тампонирующая повязка Vendaje compresivo - Bande extensible + Bande compressive Bandaż (uciskowy) Nyomókötszer Bendaggio compressivo @@ -637,44 +713,44 @@ 包扎绷带 包紮繃帶 - + Used to pack medium to large wounds and stem the bleeding Wird verwendet, um mittlere bis große Wunden abzudecken und Blutungen zu stoppen Для тампонирования ран среднего и большого размера и остановки кровотечения. Se utiliza para vendar heridas medianas o grandes y detener el sangrado - Utilisé pour couvrir des blessures moyennes et grandes, ralentit le saignement. + Utilisé 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. 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í - 弾性包帯は粘着フィルム状で、普通から大きめなケガにつかい止血します。 + 粘着フィルム状で、普通から大きめなケガに使い止血します。 중형 또는 대형 상처를 채우고 출혈을 막기위해 쓰입니다 用于包扎中到大型伤口, 并防止出血 用於包紮中到大型傷口, 並防止出血 - + A bandage used to pack the wound to stem bleeding and facilitate wound healing. Packing a wound is an option in large polytrauma injuries. Повязка для тампонирования раны, остановки кровотечения и лучшего заживления. При тяжёлых сочетанных ранениях возможно тампонирование раны. Se utiliza para detener la hemorragia de una herida y favorecer su cicatrización. Se usa en grandes lesiones o politraumatismos. - Bandage servant à recouvrir les blessures pour arrêter les hémoragies et faciliter la guérison. Recouvrir une blessure est optionnel dans le cas de blessures polytraumatiques. + 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. 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í. - 包帯をつかうと出血の原因を取りのぞき、それを促進させます。また大きめな多発性外傷にたいしても使えます。 + 包帯を使うと出血元を塞ぎ、怪我の治癒を促進させます。また大きめ多発性外傷に対しても使えます。 출혈을 막고 상처를 치유하기 위한 붕대. 다발성외상의 경우 상처를 채우는것도 한 가지 방법입니다. 用于包扎中到大型伤口, 并防止出血, 为在大型多处性伤口的选项之一! 用於包紮中到大型傷口, 並防止出血, 為在大型多處性傷口的選項之一! - + Bandage (Elastic) Bandage (Elastisch) Повязка (давящая) Vendaje (Elástico) - Bande compressive + Bande extensible Bandaż (elastyczny) Obvaz (Elastický) Rögzító kötszer @@ -685,12 +761,12 @@ 弹性绷带 彈性繃帶 - + Bandage kit, Elastic Elastische Binde (Kompressionsbinde) Давящая повязка Kit de vendaje (Elástico) - Bande compressive + Bande de crêpe extensible Bandaż elastyczny służy do opatrywania ran ciętych oraz kłutych. Dobrze radzi sobie również ze zgniecieniami tkanek miękkich oraz rozerwaniami powierzchni skóry. Rugalmas kötszercsomag, "rögzítő" Kit di bendaggio, elastico @@ -701,11 +777,11 @@ 弹性绷带 彈性繃帶 - + Allows an even compression and extra support to the injured area. Ermöglicht eine gleichmäßige Kompression und zusätzliche Unterstützung für den verletzten Bereich. Давящая повязка обеспечивает равномерное сжатие и дополнительную поддержку повреждённой области - Ce bandage peut être utilisé pour compresser la plaie afin de ralentir le saignement et assurer la tenue du bandage lors de mouvement. + Permet une compression uniforme et un maintien supplémentaire de la zone blessée. 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. @@ -717,7 +793,7 @@ 可对伤口持续压迫并固定以防止伤口情况变严重 可對傷口持續壓迫並固定以防止傷口情況變嚴重 - + Tourniquet (CAT) Tourniquet [CAT] Жгут @@ -733,7 +809,7 @@ 军用止血带 軍用止血帶 - + Slows down blood loss when bleeding Замедляет кровопотерю при кровотечении Reduce la velocidad de pérdida de sangre @@ -744,28 +820,42 @@ Rallenta la perdita di sangue in caso di sanguinamento Reduz a velocidade da perda de sangue Zpomaluje ztráty krve při krvácení - 出血しているときに、流れ出る量をへらします。 + 出血時に失血量を減らします。 출혈 시 혈액손실을 늦춰줍니다 减缓失血的速度 減緩失血的速度 - + A constricting device used to compress venous and arterial circulation in effect inhibiting or slowing blood flow and therefore decreasing loss of blood. Жгут используется для прижатия сосудов к костным выступам, которое приводит к остановке или значительному уменьшению кровотечения Dispositivo utilizado para eliminar el pulso distal y de ese modo controlar la pérdida de sangre - Un dispositif permettant de compresser les artères et veines afin de ralentir l'hémorragie. + Dispositif permettant de comprimer fortement les veines et artères, ce qui a pour effet de ralentir, voire d'arrêter la circulation sanguine.\nDiminue donc drastiquement les pertes de sang. 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. 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. - 止血帯は静脈や動脈へ圧力をかけ、循環を遅らせることで血液の流れをおそくし、失血を防ぎます。 + 止血帯は静脈や動脈へ圧力をかけ、循環を遅らせることで血液の流れを遅し失血を防ぎます。 정맥과 동맥을 압축시키켜 혈액순환을 억제 혹은 늦추게하여 혈액손실을 줄이는 도구입니다. 用于压迫静脉与动脉的血液流动, 达到减缓失血速度的目的 用於壓迫靜脈與動脈的血液流動, 達到減緩失血速度的目的 - + + Splint + Шина + 添え木 + Attelle + Tala + + + Stabilizes a fractured limb + Стабилизирует перелом конечности + 骨折部位を安定させます。 + Stabilise un membre fracturé + Estabiliza um membro fraturado. + + Morphine autoinjector Morphium-Autoinjektor Морфин в пневмошприце @@ -781,7 +871,7 @@ 吗啡自动注射器 嗎啡自動注射器 - + Used to combat moderate to severe pain experiences Wird verwendet um moderate bis starke Schmerzen zu lindern. Для снятия средних и сильных болевых ощущений @@ -792,28 +882,28 @@ 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í - 戦闘が収まったとき、痛みにたいしてつかいます。 + 戦闘が収まった時に痛みに対して使います。 심한 통증을 완화하는데 쓰입니다 减低中度至重度的疼痛感 減低中度至重度的疼痛感 - + An analgesic used to combat moderate to severe pain experiences. Обезболивающее для снятия средних и сильных болевых ощущений. Analgésico usado para combatir los estados dolorosos de moderados a severos. - Un analgésique puissant servant à réduire les douleurs modérées à sévères. + Un analgésique puissant soulageant les douleurs modérées à sévères. Organiczny związek chemiczny z grupy alkaloidów. Ma silne działanie przeciwbólowe. Ein Schmerzmittel um mäßige bis starke Schmerzen zu behandeln Egy fájdalomcsillapító anyag, jellemzően mérsékelt vagy erős fájdalom esetén alkalmazandó. Un analgesico usato per combattere il dolore. Um analgésico usado para combater dores moderadas e fortes. Analgetikum slouží k tlumení středně těžkých a těžkých bolestí - 戦闘が収まったとき、モルヒネを痛みにたいしてつかいます。 + 戦闘が収まった時にモルヒネを痛みに対して使います。 심한 통증을 완화하기 위해 쓰이는 진통제입니다. 止痛药的一种, 用于减低中度至重度的疼痛感 止痛藥的一種, 用於減低中度至重度的疼痛感 - + Adenosine autoinjector Adenosin-Autoinjektor Asenosina auto-inyectable @@ -828,7 +918,7 @@ 腺苷自动注射器 腺苷自動注射器 - + Used to counter effects of Epinephrine Wird verwendet um die Symptome von Epiniphrin zu lindern Utilizada para contrarrestar los effectos de la Epinefrina @@ -838,27 +928,27 @@ Slouží jako protiváha Adrenalinu Usado para combater os efeitos da Epinefrina Используется для купирования эффектов адреналина - アドレナリンの反対の効果としてつかいます。 + アドレナリンの反対の効果として使います。 에피네프린 대응책으로 쓰입니다 用来对付肾上腺素的影响 用來對付腎上腺素的影響 - + A drug used to counter the effects of Epinephrine Ein Medikament, das die Symptome von Epiniphrin bekämpft. 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 + Un composé utilisé pour contrer les effets de l'épinéphrine. Medicamento usato per contrastare l'effetto dell'epinefrina Droga používaná k tlumení efektu Adrenalinu Uma droga usada para combater os efeitos da Epinefrina Препарат используется для купирования эффектов адреналина - つかうと、アドレナリンと反対の効果がでます。 + 使うとアドレナリンと反対の効果が出ます。 에피네프린에 대응용으로 쓰이는 약품 一种药物用于减低肾上腺素的效果 一種藥物用於減低腎上腺素的效果 - + Atropine autoinjector Атропин в пневмошприце Atropina auto-inyectable @@ -874,39 +964,39 @@ 阿托品自动注射器 阿托品自動注射器 - + Used in NBC scenarios Применяется для защиты от ОМП Usado en escenarios NBQ - Utilisé en cas d'attaque CBRN + Utilisé en cas d'attaque CBRN. Atropina. Stosowana jako lek rozkurczowy i środek rozszerzający źrenice. Verwendet bei ABC-Kontamination NBK helyzetek esetén használandó Usato in situazioni con gas nervino. Usado em casos de ataque QBRN Používá se v přítomnosti nervových plynů - 核・生物・化学兵器がつかわれている条件下にてつかいます。 + 核・生物・化学兵器による汚染環境下にて使います。 핵,생물,화학 상황에 쓰입니다 使用于核生化污染的情况 使用於核生化汙染的情況 - + A drug used by the Military in NBC scenarios. Препарат, используемый в войсках для защиты от оружия массового поражения. Medicamento usado por militares en escenarios NBQ - Médicament utilisé par l'armée en cas d'attaque CBRN + Médicament utilisé par l'armée en cas d'attaque CBRN. Atropina. Stosowana jako lek rozkurczowy i środek rozszerzający źrenice. Środek stosowany w przypadku zagrożeń NBC. Ein Medikament, das vom Militär bei ABC-Kontamination verwendet wird. Egy instabil alkaloid, NBK helyzetek esetén a katonai szervezetek veszik használatba. 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. - 核・生物・化学兵器がつかわれている条件下にてつかいます。 + 核・生物・化学兵器による汚染環境下にて使います。 핵,생물,화학 상황에 쓰이는 군용 약품 军用神经解毒针, 用来应付核生化污染的情况. 軍用神經解毒針, 用來應付核生化汙染的情況. - + Epinephrine autoinjector Адреналин в пневмошприце Epinefrina auto-inyectable @@ -922,11 +1012,11 @@ 肾上腺素自动注射器 腎上腺素自動注射器 - + Increase heart rate and counter effects given by allergic reactions Стимулирует работу сердца и купирует аллергические реакции Aumenta la frecuencia cardiaca y contraresta los efectos de las reacciones alérgicas - Augmente la fréquence cadiaque et annule les effets d'une réaction anaphylactique + Augmente la fréquence cadiaque et annule les effets d'une réaction anaphylactique. Adrenalina. Przyśpiesza tętno oraz zwiększa ciśnienie krwi a także przeciwdziała efektom wywołanym przez reakcje alergiczne. Steigert die Herzfrequenz und bekämpft Symptome von allergischen Reaktionen. Növeli a szívverést és ellenzi az allergiás reakciók hatásait @@ -938,23 +1028,23 @@ 增加心跳速率的一种药物 增加心跳速率的一種藥物 - + A drug that works on a sympathetic response to dilate the bronchi, increase heart rate and counter such effects given by allergic reactions (anaphylaxis). Used in sudden cardiac arrest scenarios with decreasing positive outcomes. Препарат, вызывающий симпатическую реакцию, приводящую к расширению бронхов, увеличению частоты сердечных сокращений и купированию аллергических реакций (анафилактического шока). Применяется при остановке сердца с уменьшенной вероятностью благоприятного исхода. Medicamento que dilata los bronquios, aumenta la frecuencia cardiaca y contrarresta los efectos de las reacciones alérgicas (anafilaxis). Se utiliza en caso de paros cardiacos repentinos. - Medicament qui fonctionne sur le système nerveux sympathique créant une dilatation des bronches, augmente la fréquence cardiaque et annule les effets d'une réaction allergique (anaphylaxie). Utilisé lors d'arrêt cardio-respiratoire pour augmenter les chances de retrouver un pouls. + Médicament qui agit sur la réponse sympathique afin de dilater les bronches, augmenter le rythme cardiaque et contrer les effets provoqués par les réactions allergiques (anaphylaxie).\nUtilisé dans les scénarios d'arrêt cardiaque soudain, avec des résultats décroissants. EpiPen z adrenaliną ma działanie sympatykomimetyczne, tj. pobudza receptory alfa- i beta-adrenergiczne. Pobudzenie układu współczulnego prowadzi do zwiększenia częstotliwości pracy serca, zwiększenia pojemności wyrzutowej serca i przyśpieszenia krążenia wieńcowego. Pobudzenie oskrzelowych receptorów beta-adrenergicznych wywołuje rozkurcz mięśni gładkich oskrzeli, co w efekcie zmniejsza towarzyszące oddychaniu świsty i duszności. Una sostanza che permette di dilatare i bronchi, aumentare il battito cardiaco e combattere effetti di reazioni allergiche. Usato anche in casi di arresto cardiaco. Ein Medikament, das die Bronchien erweitert, die Herzfrequenz erhöht und Symptome von allergischen Reaktionen (Anaphylaxie) bekämpft. Wird bei plötzlichem Herzstillstand verabreicht. Uma droga trabalha dilatando os bronquios, aumentando a frequência cardíaca e combate efeitos de reações alérgicas(anáfilaticas). Usado em casos de parada cardiaca com poucas changes de recuperação. Egy hormon, mely a szimpatikus idegrendszer által kitágítja a hörgőket, valamint megnöveli a szívverést, ezzel ellensúlyozva ilyen jellegű allergiás reakciókat (anafilaxiás sokk). Hirtelen szívmegállás esetén is használt, idő alatt csökkenő hatásfokkal. Zúžení periferních cév díky působení na alfa receptory a následné kontrakci hladkých svalů, tím dochází k tzv. centralizaci oběhu, krev se soustřeďuje v životně důležitých centrálních orgánech (srdce, mozek, plíce), působí také pozitivně na srdeční činnost a dochází ke zvýšení krevního tlaku a tepu. Dále se používá při náhlé srdeční zástavě. - 薬は気管支を拡張するよう交感神経を拡張させ、心拍数を増加させます。それにアレルギー反応を収める効果もあります(アナフィラキシー ショック)。得られる効果は少ないですが、心停止している場合などにつかわれます。 + 気管支を拡張するよう交感神経を拡張させ、心拍数を増加させます。それにアレルギー反応を収める効果もあります (アナフィラキシー ショック)。得られる効果は少ないですが、心停止している場合などにも使われます。 기관지를 확장시키는 교감 신경 반응을 이끌어내는 약물로써, 심박을 높이고 알러지 효과에 대응합니다(아나필락시스). 심폐가 정지하는 경우 호전이 되지않을때 사용합니다. 俗称强心针, 为一种支气管扩张药物, 会增加心跳速率并减缓过敏反应(过敏性休克), 在心跳骤停时有恢复心跳的效果! 俗稱強心針, 為一種支氣管擴張藥物, 會增加心跳速率並減緩過敏反應(過敏性休克), 在心跳驟停時有恢復心跳的效果! - + Plasma IV (1000ml) Плазма для в/в вливания (1000 мл) Plasma IV (1000ml) @@ -970,11 +1060,11 @@ 血浆 (1000ml) 血漿 (1000ml) - + A volume-expanding blood supplement. Дополнительный препарат, применяемый при возмещении объема крови. Suplemento para expandir el volumen sanguíneo. - Supplément sanguin visant à remplacer les volumes perdus. + Substitut sanguin visant à remplacer les volumes perdus. Składnik krwi, używany do zwiększenia jej objętości. Egy térfogatnövelő vérkiegészítmény. Aiuta ad aumentare il volume sanguigno. @@ -986,11 +1076,11 @@ 可快速得到血液补充 可快速得到血液補充 - + A volume-expanding blood supplement. Дополнительный препарат, применяемый при возмещении объема крови. Suplemento para expandir el volumen sanguíneo. - Supplément visant à remplacer le volume sanguin perdu et remplace les plaquettes. + Substitut visant à remplacer le volume sanguin perdu. Składnik krwi, używany do zwiększenia jej objętości. Egy térfogatnövelő vérkiegészítmény. Aiuta ad aumentare il volume sanguigno. @@ -1002,11 +1092,11 @@ 可快速得到血液补充 可快速得到血液補充 - + Plasma IV (500ml) Плазма для в/в вливания (500 мл) Plasma IV (500ml) - Plasma IV (500ml) + Plasma IV (500 ml) Osocze IV (500ml) Plasma IV (500ml) Vérplazma-infúzió (500ml) @@ -1018,11 +1108,11 @@ 血浆 (500ml) 血漿 (500ml) - + Plasma IV (250ml) Плазма для в/в вливания (250 мл) Plasma IV (250ml) - Plasma (250ml) + Plasma IV (250 ml) Osocze IV (250ml) Plasma IV (250ml) Vérplazma-infúzió (250ml) @@ -1034,11 +1124,11 @@ 血浆 (250ml) 血漿 (250ml) - + Blood IV (1000ml) Кровь для переливания (1000 мл) Sangre IV (1000ml) - Culot sanguin IV (1000ml) + Culot sanguin IV (1000 ml) Krew IV (1000ml) Blut IV (1000ml) Vér-infúzió (1000ml) @@ -1050,11 +1140,11 @@ 血液 (1000ml) 血液 (1000ml) - + Blood IV, for restoring a patients blood (keep cold) Пакет крови для возмещения объёма потерянной крови (хранить в холодильнике) Sangre intravenosa, para restarurar el volumen sanguíneo (mantener frío) - Culot sanguin O-, utilisé seulement lors de perte sanguine majeure afin de remplacer le volume sanguin perdu. Habituellement utilisé lors du transport ou dans un établissement de soins. + Culot sanguin pour transfustion IV, restaure le sang d'un patient (conserver au froid !) Krew IV, używana do uzupełnienia krwi u pacjenta, trzymać w warunkach chłodniczych. Vér-infúzió, intravénás bejuttatásra egy páciensnek (hidegen tárolandó) Sangue usato per ripristinare pazienti in cui si è verificata una perdita di sangue (conservare al fresco) @@ -1066,13 +1156,13 @@ 血液, 用于补充伤者流失的血液 (需冷藏) 血液, 用於補充傷者流失的血液 (需冷藏) - + O Negative infusion blood used in strict and rare events to replenish blood supply usually conducted in the transport phase of medical care. Кровь I группы, резус-отрицательная, применяется по жизненным показаниям для возмещения объема потерянной крови на догоспитальном этапе оказания медицинской помощи. Krew 0 Rh-, używana w rzadkich i szczególnych przypadkach do uzupełnienia krwi u pacjenta, zazwyczaj w trakcie fazie transportu rannej osoby do szpitala. Utilice sólo durante gran pérdida de sangre para reemplazar el volumen de sangre perdida. Uso habitual durante el transporte de heridos. Sangue 0 negativo usato per ripristinare sangue in pazienti in cui si è verificata una perdita di sangue. - Culot sanguin O- utilisé dans de rares et stricts cas pour compléter une perte de sang importante. Administré normalement lors d'un MEDEVAC. + Culot sanguin O-, utilisé en cas de perte de sang importante, afin de rétablir un volume normal.\nAdministré normalement lors d'un MEDEVAC. O Negative Blutinfusion wird nur in seltenen Fällen verwendet, um den Bluthaushalt des Patienten zu ergänzen. Wird in der Regel wärend der Transportphase durchgeführt. Sangue O- , utilizado em casos raros para rapidamente repor o sangue. Uso habitual ocorre durante o transporte ou em estações de tratamento. Nullás vércsoportú, Rh-negatív vér-infúzió, melyet kritikus és ritka helyzetekben vérutánpótlásra használnak, jellemzően az orvosi ellátás szállítási fázisa közben. @@ -1082,11 +1172,11 @@ O型负值注射用血液, 在紧急情况时使用, 用于补充伤者流失的血液 O型負值注射用血液, 在緊急情況時使用, 用於補充傷者流失的血液 - + Blood IV (500ml) Кровь для переливания (500 мл) Sangre IV (500ml) - Culot sanguin IV (500ml) + Culot sanguin IV (500 ml) Krew IV (500ml) Blut IV (500ml) Vér-infúzió (500ml) @@ -1098,11 +1188,11 @@ 血液 (500ml) 血液 (500ml) - + Blood IV (250ml) Кровь для переливания (250 мл) Sangre IV (250ml) - Culot sanguin IV (250ml) + Culot sanguin IV (250 ml) Krew IV (250ml) Blut IV (250ml) Vér-infúzió (250ml) @@ -1114,11 +1204,11 @@ 血液 (250ml) 血液 (250ml) - + Saline IV (1000ml) Физраствор для в/в вливания (1000 мл) Salino IV (1000ml) - Solution saline IV (1000ml) + Solution saline IV (1000 ml) Sól fizjologiczna IV (1000ml) Kochsalzlösung (1000ml) 0,9%-os sósvíz-infúzió (1000ml) @@ -1130,11 +1220,11 @@ 生理食盐水 (1000ml) 生理食鹽水 (1000ml) - + Saline IV, for restoring a patients blood Пакет физраствора для возмещения объёма потерянной крови Solución salina intravenosa, para restaurar el volumen sanguíneo - Solution saline, pour rétablir temporairement la tension artérielle + Solution saline, pour rétablir en urgence le volume sanguin. 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). 0,9%-os sósvíz-infúzió, a páciens vérmennyiségének helyreállítására Soluzione salina, usata per ripristinare sangue nei pazienti. @@ -1146,11 +1236,11 @@ 生理食盐水, 用于恢复伤者血液 生理食鹽水, 用於恢復傷者血液 - + A medical volume-replenishing agent introduced into the blood system through an IV infusion. Пакет физиологического раствора для возмещения объёма потерянной крови путем внутривенного вливания Suero fisiológico inoculado al torrente sanguíneo de forma intravenosa. - Un remplacant temporaire pour rétablir la tension artérielle lors de perte sanguine, administré par intra-veineuse + Un agent médical permettant de reconstituer le volume sanguin.\nA 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. @@ -1162,11 +1252,11 @@ 利用静脉注射进入人体血液系统, 帮助伤者血液恢复 利用靜脈注射進入人體血液系統, 幫助傷者血液恢復 - + Saline IV (500ml) Физраствор для в/в вливания (500 мл) Salino IV (500ml) - Solution saline IV (500ml) + Solution saline IV (500 ml) Sól fizjologiczna IV (500ml) Kochsalzlösung (500ml) 0,9%-os sósvíz-infúzió (500ml) @@ -1178,11 +1268,11 @@ 生理食盐水 (500ml) 生理食鹽水 (500ml) - + Saline IV (250ml) Физраствор для в/в вливания (250 мл) Salino IV (250ml) - Solution saline IV (250ml) + Solution saline IV (250 ml) Sól fizjologiczna IV (250ml) Kochsalzlösung (250ml) 0,9%-os sósvíz-infúzió (250ml) @@ -1194,11 +1284,11 @@ 生理食盐水 (250ml) 生理食鹽水 (250ml) - + Basic Field Dressing (QuikClot) Первичный перевязочный пакет (QuikClot) Vendaje básico (QuickClot) - Bandage basique (Hémostatique) + Pansement hémostatique (Quikclot) Opatrunek QuikClot ACS Verbandpäckchen (QuikClot) Általános zárókötszer (QuikClot) @@ -1210,11 +1300,11 @@ 基本战地包扎 (止血粉) 基本戰地包紮 (止血粉) - + QuikClot bandage Гемостатический пакет QuikClot Vendaje QuikClot - Bandage hémostatique + Bande de gaze hémostatique Proszkowy opatrunek adsorbcyjny przeznaczony do tamowania zagrażających życiu krwawień średniej i dużej intensywności. Bandage mit Gerinnungsmittel QuikClot kötszer @@ -1226,10 +1316,10 @@ 止血粉绷带 止血粉繃帶 - + Hemostatic bandage with coagulant that stops bleeding. Медицинский коагулянт для экстренной остановки кровотечения - Un bandage aidant à coaguler les saignements mineurs à moyens. + Bande de gaze hémostatique, impreignée d'un agent coagulant, afin de maitriser et stopper rapidement une hémorragie. Proszkowy opatrunek adsorpcyjny przeznaczony do tamowania zagrażających życiu krwawień średniej i dużej intensywności. Vendaje hemostático con coagulante que detiene el sangrado. Verband mit Gerinnungsmittel, um starke Blutung zu behandeln. @@ -1237,12 +1327,12 @@ Bendaggio emostatico con coagulante che permette di arrestare perdite di sangue Bandagem Hemostática com coagulante que controla hemorragia médias e grandes com risco de vida. Hemostatický obvaz určený k zástavě krvácení - 血液凝固剤をふくむ包帯により、止血できます。 + 血液凝固剤を含む包帯により、止血できます。 지혈시 사용하는 붕대로 혈액 응고제를 포함하고있습니다. 包含止血粉成分的止血绷带, 可用于止血 包含止血粉成分的止血繃帶, 可用於止血 - + Personal Aid Kit Аптечка Trousse sanitaire @@ -1258,39 +1348,39 @@ 个人急救包 個人急救包 - + Includes various treatment kit needed for stitching or advanced treatment Содержит различные материалы и инструменты для зашивания ран и оказания специальной медпомощи. Incluye material médico para tratamientos avanzados - Inclut du matériel medical pour les traitements délicats, tel les points de suture. + Contient tout le matériel médical requis pour la suture ou les traitements avancés Zestaw środków medycznych do opatrywania ran i dodatkowego leczenia po-urazowego. Beinhaltet medizinisches Material für fortgeschrittene Behandlung und zum Nähen. Változatos segédfelszereléseket tartalmaz sebvarráshoz és haladó elsősegélynyújtáshoz 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 - 縫合や高度な処置に必要とされる、さまざまな治療器具が含まれています。 + 縫合や高度な処置に必要とされる、様々な治療器具が含まれています。 봉합및 고급 조치에 필요한 다양한 치료 도구가 있습니다. 包含各种医疗套件, 以及进阶伤口系统需要的缝合用品 包含各種醫療套件, 以及進階傷口系統需要的縫合用品 - + Personal Aid Kit for in field stitching or advanced treatment W znacznym stopniu poprawia stan pacjenta Полевая аптчека для продвинутого лечения и зашивания ран Persönliches Erste-Hilfe-Set zum ambulanten Nähen und fortgeschrittener Behandlung. - Inclut du matériel medical pour les traitements délicats, tel les points de suture. + A utiliser pour les sutures sur le terrain, ou pour les traitements avancés. Equipo de primeros auxilios para sutura de campaña o tratamientos avanzados Elsősegélycsomag, terepen való sebvarráshoz és haladó ellátáshoz 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. - 戦場で縫合や高度な処置に必要とされる、さまざまな治療器具が含まれています。 + 戦場で縫合や高度な処置に必要とされる、様々な治療器具が含まれています。 야전에서 봉합및 고급 조치를 위한 개인응급키트 个人急救包可用于战地缝合手术或进阶伤口系统使用 個人急救包可用於戰地縫合手術或進階傷口系統使用 - + Use Personal Aid Kit Erste-Hilfe-Set benutzen Использовать аптечку @@ -1301,12 +1391,12 @@ Usar o kit de primeiros socorros Použít osobní lékárničku (PAK) Usa il pronto soccorso personale - 応急処置キットをつかう + 応急処置キットを使う 개인 응급 키트사용하기 使用个人急救包 使用個人急救包 - + Surgical Kit Trousse chirurgicale Хирургический набор @@ -1322,9 +1412,9 @@ 手术包 手術包 - + Surgical Kit for in field advanced medical treatment - Trousse chirurgicale pour le traitement sur le terrain + Trousse chirurgicale pour le traitement avancé sur le terrain Набор для хирургической помощи в полевых условиях Kit quirúrgico para el tratamiento avanzado en el campo de batalla Zestaw pozwalający na zszywanie ran w polu @@ -1333,28 +1423,28 @@ 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 - 縫合キットは戦場で高度な処置をするためにつかわれます。 + 縫合キットは戦場で高度な処置をする為に使われます。 야전 상황에서 고급 의료 처치를 위해 사용되는 봉합 키트 用于在战场上为伤口进行缝合(需要开启进阶伤口系统) 用於在戰場上為傷口進行縫合(需要開啟進階傷口系統) - + Surgical Kit for in field advanced medical treatment Набор для хирургической помощи в полевых условиях Kit quirúrgico para el tratamiento avanzado en el campo de batalla Zestaw pozwalający na zszywanie ran w polu Operationsset für fortgeschrittene medizinische Feldversorgung - Trousse chirurgicale pour le traitement sur le terrain + Trousse chirurgicale pour le traitement sur le terrain. Sebészeti készlet komplex orvosi feladatok terepen való ellátására 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 - 縫合キットは戦場で高度な処置をするためにつかわれます。 + 縫合キットは戦場で高度な処置をする為に使われます。 야전 상황에서 고급 의료 처치를 위해 사용되는 봉합 키트 用于在战场上为伤口进行缝合(需要开启进阶伤口系统) 用於在戰場上為傷口進行縫合(需要開啟進階傷口系統) - + Use Surgical Kit Operationsset benutzen Usa kit chirurgico @@ -1365,12 +1455,12 @@ Sebészeti készlet használata Použít chirurgickou sadu Usar kit cirúrgico - 縫合キットをつかう + 縫合キットを使う 봉합키트 사용하기 使用手术包 使用手術包 - + Bodybag Housse mortuaire Мешок для трупов @@ -1386,7 +1476,7 @@ 尸袋 屍袋 - + A bodybag for dead bodies Housse de transport des corps Мешок для упаковки трупов @@ -1397,12 +1487,12 @@ Una sacca nera per trasportare cadaveri. Um saco para corpos mortos Pytel na mrtvoly - 死体袋は死体を入れるためにつかいます + 死体袋は死体を入れる為に使います。 시체를 운반할때 쓰는 가방입니다 用来装尸体用 用來裝屍體用 - + A bodybag for dead bodies Housse de transport des corps Мешок для упаковки трупов @@ -1413,28 +1503,28 @@ Una sacca nera per trasportare cadaveri. Um saco para corpos mortos. Pytel na mrtvoly - 死体袋は死体を入れるためにつかいます + 死体袋は死体を入れる為に使います。 시체를 운반할때 쓰는 가방입니다 用来装尸体用 用來裝屍體用 - + No injuries on this bodypart... Körperteil nicht verletzt... Non ci sono ferite in questa parte del corpo... Данная часть тела не повреждена... - Aucune blessures sur cette partie du corps... + Aucune blessure sur cette partie du corps... Brak obrażeń na tej części ciała... Sin heridas en esta parte del cuerpo... Ezen a testrészen nincs sérülés... Žádné zranění na této části těla... Nenhum ferimento nesta parte do corpo... - この身体は怪我をしていません・・・ + この部分には怪我をしていません・・・ 이 부위에는 부상이 없습니다... 此身体部位没有受伤 此身體部位沒有受傷 - + Inject Adenosine Adenosin injizieren Inyectar Adenosina @@ -1449,7 +1539,7 @@ 注射腺苷 注射腺苷 - + Inject Atropine Atropin injizieren Inyectar Atropina @@ -1465,7 +1555,7 @@ 注射阿托品 注射阿托品 - + Inject Epinephrine Epinephrine injizieren Inyectar Epinefrina @@ -1481,7 +1571,7 @@ 注射肾上腺素 注射腎上腺素 - + Inject Morphine Morphin injizieren Inyectar Morfina @@ -1497,7 +1587,7 @@ 注射吗啡 注射嗎啡 - + Transfuse Blood Bluttransfusion Transfundir sangre @@ -1513,7 +1603,7 @@ 输血液 輸血液 - + Transfuse Plasma Plasmatransfusion Transfundir plasma @@ -1529,7 +1619,7 @@ 输血浆 輸血漿 - + Transfuse Saline Salzlösungstransfusion Transfundir salino @@ -1545,7 +1635,7 @@ 注射生理食盐水 注射生理食鹽水 - + Apply Tourniquet Tourniquet anwenden Aplicar torniquete @@ -1561,7 +1651,7 @@ 使用军用止血带 使用軍用止血帶 - + Bandage Verbinden Venda @@ -1577,7 +1667,7 @@ 绷带 繃帶 - + Bandage Head Kopf verbinden Vendar la cabeza @@ -1593,7 +1683,7 @@ 绷带包扎 头部 繃帶包紮 頭部 - + Bandage Torso Torso verbinden Vendar el torso @@ -1609,7 +1699,7 @@ 绷带包扎 身体 繃帶包紮 身體 - + Bandage Left Arm Linken Arm verbinden Vendar el brazo izquierdo @@ -1625,7 +1715,7 @@ 绷带包扎 左手 繃帶包紮 左手 - + Bandage Right Arm Rechten Arm verbinden Vendar el brazo derecho @@ -1641,7 +1731,7 @@ 绷带包扎 右手 繃帶包紮 右手 - + Bandage Left Leg Linkes Bein verbinden Vendar la pierna izquierda @@ -1657,7 +1747,7 @@ 绷带包扎 左脚 繃帶包紮 左腳 - + Bandage Right Leg Rechtes Bein verbinden Vendar la pierna derecha @@ -1673,7 +1763,7 @@ 绷带包扎 右脚 繃帶包紮 右腳 - + Injecting Morphine... Morphin injizieren... Inyectando Morfina... @@ -1689,7 +1779,7 @@ 吗啡注射中... 嗎啡注射中... - + Injecting Epinephrine... Epinephrin injizieren... Inyectando Epinefrina... @@ -1705,7 +1795,7 @@ 肾上腺素注射中... 腎上腺素注射中... - + Injecting Adenosine... Adenosin injizieren... Inyectando Adenosina... @@ -1720,7 +1810,7 @@ 腺苷注射中... 腺苷注射中... - + Injecting Atropine... Atropin injizieren... Inyectando Atropina... @@ -1736,7 +1826,7 @@ 阿托品注射中 ... 阿托品注射中 ... - + Transfusing Blood... Bluttransfusion... Transfusión de sangre... @@ -1752,7 +1842,7 @@ 输血液中 ... 輸血液中 ... - + Transfusing Saline... Salzlösungtransfusion... Transfusión de salino... @@ -1768,7 +1858,7 @@ 施打生理食盐水中 ... 施打生理食鹽水中 ... - + Transfusing Plasma... Plasmatransfusion... Transfusión de plasma... @@ -1784,7 +1874,7 @@ 输血浆中 ... 輸血漿中 ... - + Bandaging... Verbinden... Vendando... @@ -1800,7 +1890,7 @@ 绷带包扎中 ... 繃帶包紮中 ... - + Applying Tourniquet... Setze Tourniquet an... Aplicando torniquete... @@ -1816,7 +1906,7 @@ 使用军用止血带中 ... 使用軍用止血帶中 ... - + Field Dressing Wundverband Compresa de campaña @@ -1832,7 +1922,7 @@ 基础绷带 基礎繃帶 - + Packing Bandage Mullbinde Vendaje compresivo @@ -1840,7 +1930,7 @@ Bandaż uciskowy Nyomókötszer Bendaggio compressivo - Bande extensible + Bandage compressif Bandagem de Compressão Obvaz Tlakový 弾性包帯 @@ -1848,14 +1938,14 @@ 包扎绷带 包紮繃帶 - + Elastic Bandage Elastischer Verband Vendaje elástico Давящая повязка Obavaz Elastický Bandaż elastyczny - Bande compressive + Bandage extensible Rögzitő kötszer Bendaggio elastico Bandagem Elástica @@ -1864,7 +1954,7 @@ 弹性绷带 彈性繃帶 - + QuikClot QuikClot QuikClot @@ -1880,7 +1970,7 @@ 止血粉 止血粉 - + Check Pulse Puls überprüfen Comprobar pulso @@ -1891,12 +1981,12 @@ Pulzus ellenőrzése Controlla il polso Checar Pulso - 心拍数をはかる + 心拍数を計る 맥박 확인 检查脉搏 檢查脈搏 - + Check Blood Pressure Blutdruck überprüfen Comprobar presión arterial @@ -1907,12 +1997,12 @@ Vérnyomás megmérése Controlla pressionsa sanguigna Chegar Pressão Sanguínea - 血圧をはかる + 血圧を計る 혈압 확인 检查血压 檢查血壓 - + No entries on this triage card. Keine Einträge auf der Triagekarte Nessuna voce sulla Triage Card @@ -1928,7 +2018,7 @@ 此检伤分类卡上没有任何资料 此檢傷分類卡上沒有任何資料 - + Tourniquet Tourniquet Torniquete @@ -1944,7 +2034,7 @@ 军用止血带 軍用止血帶 - + Remove Tourniquet Tourniquet entfernen Quitar torniquete @@ -1955,12 +2045,26 @@ Érszorító leszedése Rimuovi laccio emostatico Remover Torniquete - 止血帯をはずす + 止血帯を外す 지혈대 제거 移除军用止血带 移除軍用止血帶 - + + Apply Splint + Наложить Шину + 添え木を当てる + Poser attelle + Aplicar Tala + + + Applying Splint... + Накладывается Шина... + 添え木を当てています・・・ + Retirer attelle + Aplicando Tala... + + Diagnose Diagnose Diagnosi @@ -1976,12 +2080,12 @@ 诊断 診斷 - + Diagnosing... Diagnostizieren... Diagnosi in corso... Диагностика... - Diagnostic en cours + Diagnostic en cours... Diagnozowanie... Diagnosticando... Diagnózis folyamatban... @@ -1992,7 +2096,7 @@ 诊断中... 診斷中... - + CPR HLW RCP @@ -2008,12 +2112,12 @@ 心肺复苏术 心肺復甦術 - + Performing CPR... HLW durchführen... Eseguendo RCP... Сердечно-лёгочная реанимация... - RCP en cours + RCP en cours... Przeprowadzanie RKO... Realizando RCP... Újraélesztés folyamatban... @@ -2024,159 +2128,178 @@ 进行心肺复苏术中... 進行心肺復甦術中... - + + CPR Success Chance + 心肺蘇生の成功率 + Chance de réussite du RCP + Шанс успешной реанимации + Chance de ter sucesso com SBV + + + Probability that cpr will be successful in restoring heart rhythm. + 心肺蘇生によって心拍を戻せる確率を決定できます。 + Probabilité de rétablir un rythme cardiaque suite à une RCP. + Вероятность успешного проведения сердечно-лёгочной реанимации (СЛР). + Probabilidade que um SBV restaurará o batimento cardíaco. + + Give Blood IV (1000ml) Bluttransfusion IV (1000ml) Dar Sangre IV (1000ml) Перелить пакет крови (1000 мл) Podaj krew IV (1000ml) - Sang en IV (1000ml) + Sang en IV (1000 ml) Podat krev. transfúzi (1000ml) Vér adása intravénásan (1000ml) Effettua trasfusione sangue EV (1˙000ml) Administrar Sangue IV (1000ml) - 血液 IV (1000ml) をあたえる + 血液 IV (1000ml) を投与 IV 혈액 수혈 (1000ml) 输血液 (1000ml) 輸血液 (1000ml) - + Give Blood IV (500ml) Bluttransfusion IV (500ml) Dar Sangre IV (500ml) Перелить пакет крови (500 мл) Podaj krew IV (500ml) - Sang en IV (500ml) + Sang en IV (500 ml) Podat krev. transfúzi (500ml) Vér adása intravénásan (500ml) Effettua trasfusione sangue EV (500ml) Administrar Sangue IV (500ml) - 血液 IV (500ml) をあたえる + 血液 IV (500ml) を投与 IV 혈액 수혈 (500ml) 输血液 (500ml) 輸血液 (500ml) - + Give Blood IV (250ml) Bluttransfusion IV (250ml) Dar Sangre IV (250ml) Перелить пакет крови (250 мл) Podaj krew IV (250ml) - Sang en IV (250ml) + Sang en IV (250 ml) Podat krev. transfúzi (250ml) Vér adása intravénásan (250ml) Effettua trasfusione sangue EV (250ml) Administrar Sangue IV (250ml) - 血液 IV (250ml) をあたえる + 血液 IV (250ml) を投与 IV 혈액 수혈 (250ml) 输血液 (250ml) 輸血液 (250ml) - + Give Plasma IV (1000ml) Plasmatransfusion IV (1000ml) Dar Plasma IV (1000ml) Перелить пакет плазмы (1000 мл) Podaj osocze IV (1000ml) - Plasma en IV (1000ml) + Plasma en IV (1000 ml) Podat plazmu (1000ml) Vérplazma adása intravénásan (1000ml) Effettua trasfusione plasma EV (1˙000ml) Administrar Plasma IV (1000ml) - 血しょう IV (1000ml) をあたえる + 血しょう IV (1000ml) を投与 IV 혈장 수혈 (1000ml) 输血浆 (1000ml) 輸血漿 (1000ml) - + Give Plasma IV (500ml) Plasmatransfusion IV (500ml) Dar Plasma IV (500ml) Перелить пакет плазмы (500 мл) Podaj osocze IV (500ml) - Plasma en IV (500ml) + Plasma en IV (500 ml) Podat plazmu (500ml) Vérplazma adása intravénásan (500ml) Effettua trasfusione plasma EV (500ml) Administrar Plasma IV (500ml) - 血しょう IV (500ml) をあたえる + 血しょう IV (500ml) を投与 IV 혈장 수혈 (500ml) 输血浆 (500ml) 輸血漿 (500ml) - + Give Plasma IV (250ml) Plasmatransfusion IV (250ml) Dar Plasma IV (250ml) Перелить пакет плазмы (250 мл) Podaj osocze IV (250ml) - Plasma en IV (250ml) + Plasma en IV (250 ml) Podat plazmu (250ml) Vérplazma adása intravénásan (250ml) Effettua trasfusione plasma EV (250ml) Administrar Plasma IV (250ml) - 血しょう IV (250ml) をあたえる + 血しょう IV (250ml) を投与 IV 혈장 수혈 (250ml) 输血浆 (250ml) 輸血漿 (250ml) - + Give Saline IV (1000ml) Kochsalzlösung IV (1000ml) Dar Salino IV (1000ml) Перелить пакет физраствора (1000 мл) Podaj sól fizjologiczną IV (1000ml) - Solution saline en IV (1000ml) + 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) Administrar Soro IV (1000ml) - 生理食塩水 IV (1000ml) をあたえる + 生理食塩水 IV (1000ml) を投与 IV 생리식염수 수혈 (1000ml) 注射生理食盐水 (1000ml) 注射生理食鹽水 (1000ml) - + Give Saline IV (500ml) Kochsalzlösung IV (500ml) Dar Salino IV (500ml) Перелить пакет физраствора (500 мл) Podaj sól fizjologiczną IV (500ml) - Solution saline en IV (500ml) + 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) Administrar Soro IV (500ml) - 生理食塩水 IV (500ml) をあたえる + 生理食塩水 IV (500ml) を投与 IV 생리식염수 수혈 (500ml) 注射生理食盐水 (500ml) 注射生理食鹽水 (500ml) - + Give Saline IV (250ml) Kochsalzlösung IV (250ml) Dar Salino IV (250ml) Перелить пакет физраствора (250 мл) Podaj sól fizjologiczną IV (250ml) - Solution saline en IV (250ml) + 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) Administrar Soro IV (250ml) - 生理食塩水 IV (250ml) をあたえる + 生理食塩水 IV (250ml) を投与 IV 생리식염수 수혈 (250ml) 注射生理食盐水 (250ml) 注射生理食鹽水 (250ml) - + Minimal + Minimal + 軽処置群 + Минимально + Aucune urgence + Mínimo - + Delayed Retrasado Срочная помощь Opóźniony - Traitement urgent + Peut attendre Verzögert Odložitelný Késleltetett @@ -2187,12 +2310,12 @@ 延后 延後 - + Immediate Inmediato Неотложная помощь Natychmiastowy - Traitement immédiat + Urgent Sofort Okamžitý Azonnali @@ -2203,7 +2326,7 @@ 紧急 緊急 - + Deceased Fallecido Труп @@ -2219,7 +2342,7 @@ 死亡 死亡 - + None Ninguno Отсутствует @@ -2235,7 +2358,7 @@ 未分类 未分類 - + Normal breathing Дыхание в норме Respiración normal @@ -2251,7 +2374,7 @@ 呼吸正常 呼吸正常 - + No breathing Keine Atmung Дыхание отсутствует @@ -2267,11 +2390,11 @@ 没有呼吸 沒有呼吸 - + Difficult breathing Дыхание затруднено Dificultad para respirar - Difficulté respiratoire + Respiratoire difficile Trudności z oddychaniem Schwere Atmung Dýchá s obtížemi @@ -2283,12 +2406,12 @@ 呼吸困难 呼吸困難 - + Almost no breathing Beinahe keine Atmung Дыхание очень слабое Casi sin respiración - Respiration faible + Respiration très faible Prawie brak oddechu Skoro nedýchá Alig van légzés @@ -2299,11 +2422,15 @@ 快要没呼吸 快要沒呼吸 - + In mild pain Hat leichte Schmerzen + 中くらいの痛みがある + Небольшая боль + Légère douleur + Com dor leve - + In pain Hat Schmerzen Испытывает боль @@ -2319,11 +2446,15 @@ 疼痛中 疼痛中 - + In severe pain Hat starke Schmerzen + ひどい痛みがある + Сильная боль + Douleur intense + Com dor intensa - + Tourniquet [CAT] Tourniquet [CAT] Жгут @@ -2339,7 +2470,7 @@ 军用止血带 軍用止血帶 - + Receiving IV [%1ml] Erhalte IV [%1ml] Recibiendo IV [%1ml] @@ -2355,7 +2486,7 @@ 接收静脉注射液中 [%1ml] 接收靜脈注射液中 [%1ml] - + Blood Pressure Tension artérielle Артериальное давление @@ -2371,9 +2502,9 @@ 血压 血壓 - + Checking Blood Pressure.. - Prise de la tension... + Prise de tension... Проверка артериального давления... Comprobando presión arterial... Sprawdzanie ciśnienia krwi... @@ -2387,12 +2518,12 @@ 检查血压中... 檢查血壓中... - + %1 checked Blood Pressure: %2 %1 kontrollierte Blutdruck: %2 %1 controllata pressione sanguigna: %2 %1 проверил артериальное давление: %2 - %1 a mesuré la tension: %2 + %1 a mesuré la tension : %2 %1 sprawdził ciśnienie krwi: %2 %1 verificada la presión arterial: %2 %1 ellenőrizte a vérnyomást: %2 @@ -2403,7 +2534,7 @@ 已由%1确认血压: %2 已由%1確認血壓: %2 - + You checked %1 Vous examinez %1 Вы осмотрели раненого %1 @@ -2419,9 +2550,9 @@ 你已经检查 %1 你已經檢查 %1 - + You find a blood pressure of %2/%3 - Vous avez mesuré une tension de %2/%3 + La tension est de %2/%3 Артериальное давление %2/%3 La Presión Arterial es %2/%3 A vérnyomás %2/%3 @@ -2435,9 +2566,9 @@ 血压为%2/%3 血壓為%2/%3 - + You find a low blood pressure - Tension basse + La tension est basse Давление низкое La presión arterial es baja Wyczuwasz niskie ciśnienie krwi @@ -2451,9 +2582,9 @@ 发现到低血压 發現到低血壓 - + You find a normal blood pressure - Tension normale + La tension est normale Давление нормальное La presión arterial es normal Wyczuwasz normalne ciśnienie krwi @@ -2467,9 +2598,9 @@ 发现到正常血压 發現到正常血壓 - + You find a high blood pressure - Tension élevée + La tension est élevée Давление высокое La presión arterial es alta Wyczuwasz wysokie ciśnienie krwi @@ -2483,9 +2614,9 @@ 发现到高血压 發現到高血壓 - + You find no blood pressure - Pas de tension + Il n'y a aucune pression sanguine Давления нет No hay presión arterial Nie wyczuwasz ciśnienia krwi @@ -2499,7 +2630,7 @@ 量不到血压 量不到血壓 - + You fail to find a blood pressure Vous n'avez pas pu mesurer de tension Артериальное давление не определяется @@ -2515,7 +2646,7 @@ 检查血压的动作失败 檢查血壓的動作失敗 - + Low Niedrig Bassa @@ -2531,7 +2662,7 @@ - + Normal Normal Normale @@ -2547,7 +2678,7 @@ 正常 正常 - + High Hoch Alta @@ -2563,12 +2694,12 @@ - + No Blood Pressure Kein Blutdruck Nessuna Pressione Sanguigna Артериальное давление отсутствует - pas de tension + Aucune pression sanguine Brak ciśnienia krwi Sin presión arterial Nincs vérnyomás @@ -2579,7 +2710,7 @@ 无血压 無血壓 - + Pulse Пульс Pouls @@ -2595,7 +2726,7 @@ 脉搏 脈搏 - + Checking Heart Rate... Vérification du pouls... Проверка пульса... @@ -2611,7 +2742,7 @@ 检查心跳中... 檢查心跳中... - + You checked %1 Вы осмотрели раненого %1 Vous examinez %1 @@ -2627,12 +2758,12 @@ 你已经检查 %1 你已經檢查 %1 - + %1 checked Heart Rate: %2 %1 kontrollierte Herzfrequenz: %2 %1 Controllata Frequenza Cardiaca: %2 %1 проверил пульс: %2 - %1 a vérifié le pouls de : %2 + %1 a vérifié le pouls : %2 %1 sprawdził tętno: %2 %1 verificado el ritmo cardíaco: %2 %1 ellenőrizte a szívverés-számot: %2 @@ -2643,7 +2774,7 @@ 已由%1确认心跳: %2 已由%1確認心跳: %2 - + None Нет Żadna @@ -2651,7 +2782,7 @@ Keine Žádný Nada - aucun + Aucun pouls Nincs Niente なし @@ -2659,12 +2790,12 @@ - + Weak Schwach Lento Слабый - lent + Lent Słabe Débil Gyenge @@ -2675,12 +2806,12 @@ 微弱 微弱 - + Normal Normal Normale Нормальный - normal + Normal Normalne Normal Normális @@ -2691,12 +2822,12 @@ 正常 正常 - + Strong Stark Veloce Сильный - rapide + Rapide Silne Fuerte Erős @@ -2707,9 +2838,9 @@ 过快 過快 - + You find a Heart Rate of %2 - %2 battements par minute + Le rythme cardiaque est de %2 Пульс %2 уд./мин. El ritmo cardíaco es de %2 Wyczuwasz tętno o wartości %2 @@ -2723,9 +2854,9 @@ 心跳为%2 心跳為%2 - + You find a weak Heart Rate - Poulslent + Rythme cardiaque lent Пульс слабый El ritmo cardíaco es débil Wyczuwasz słabe tętno @@ -2739,9 +2870,9 @@ 心跳微弱 心跳微弱 - + You find a strong Heart Rate - pouls rapide + Rythme cardiaque rapide Пульс учащенный El ritmo cardíaco está acelerado Wyczuwasz silne tętno @@ -2755,9 +2886,9 @@ 心跳过快 心跳過快 - + You find a normal Heart Rate - pouls normal + Rythme cardiaque normal Пульс в норме El ritmo cardíaco es bueno Wyczuwasz normalne tętno @@ -2771,9 +2902,9 @@ 心跳正常 心跳正常 - + You find no Heart Rate - pas de pouls + Aucun pouls Пульс не прощупывается No tiene ritmo cardíaco Wyczuwasz brak tętna @@ -2787,7 +2918,7 @@ 量不到心跳 量不到心跳 - + Response Conscience Реакция @@ -2803,9 +2934,9 @@ 反应 反應 - + You check response of patient - Vous évaluez l'état de conscience + Vous évaluez l'état de conscience du patient Вы проверяете реакцию раненого Compruebas si el paciente reacciona Sprawdzasz przytomność pacjenta @@ -2819,7 +2950,7 @@ 检查伤者的反应 檢查傷者的反應 - + %1 is responsive %1 реагирует на раздражители %1 est conscient @@ -2835,7 +2966,7 @@ %1 有反应 %1 有反應 - + %1 is not responsive %1 не реагирует на раздражители %1 est inconscient @@ -2851,7 +2982,7 @@ %1 没有反应 %1 沒有反應 - + You checked %1 Вы осмотрели раненого %1 Vous avez examiné %1 @@ -2867,7 +2998,7 @@ 你已经检查 %1 你已經檢查 %1 - + Patient %1<br/>is %2.<br/>%3.<br/>%4 Il paziente %1<br/>è %2.<br/>%3.<br/>%4 Пациент %1<br/>%2.<br/>%3.<br/>%4 @@ -2883,7 +3014,7 @@ 伤者 %1<br/>is %2.<br/>%3.<br/>%4 傷者 %1<br/>is %2.<br/>%3.<br/>%4 - + alive vivo жив @@ -2899,7 +3030,7 @@ 活着 活著 - + dead morto мёртв @@ -2915,13 +3046,13 @@ 死亡 死亡 - + He's lost some blood Ha perso poco sangue Ha perdido un poco de sangre Есть кровопотеря Er hat etwas Blut verloren - Il a perdu du sang + Il a perdu un peu de sang Stracił trochę krwi Valamennyi vért vesztett Ztratil trochu krve @@ -2931,7 +3062,7 @@ 他流失一些血液 他流失一些血液 - + He's lost a lot of blood Er hat viel Blut verloren Sok vért vesztett @@ -2947,7 +3078,7 @@ 他流失大量血液 他流失大量血液 - + He hasn't lost blood Non ha perso sangue Нет кровопотери @@ -2963,7 +3094,7 @@ 他并没有失血 他並沒有失血 - + He is in pain Sente dolori Испытывает боль @@ -2979,7 +3110,7 @@ 他感到疼痛 他感到疼痛 - + He is not in pain Non sente dolori Не испытывает боли @@ -2995,7 +3126,7 @@ 他不会疼痛 他不會疼痛 - + Bandaged Pansé Повязка наложена @@ -3011,7 +3142,7 @@ 绷带 繃帶 - + You bandage %1 (%2) Vous pansez %1 (%2) Вы перевязали раненого %1 (%2) @@ -3022,12 +3153,12 @@ Du verbindest %1 (%2) Você aplica bandagem no paciente %1 (%2) Obvazuješ %1 (%2) - %1 (%2) 包帯をつかった + %1 (%2) 包帯を使った %1 (%2) 붕대를 감았다 你正在对 %1 (%2) 包扎绷带中 你正在對 %1 (%2) 包紮繃帶中 - + %1 is bandaging you %1 vous panse %1 перевязывает вас @@ -3043,7 +3174,7 @@ %1 正在对你包扎绷带中 %1 正在對你包紮繃帶中 - + You start stitching injuries from %1 (%2) Вы зашиваете ранения от %1 (%2) Du nähst die Wunden von %1 (%2) @@ -3054,17 +3185,17 @@ Stai suturando le ferite di %1 (%2) Você começa a suturar os ferimentos do %1 (%2) Zašíváš rány %1 (%2) - あなたは %1 (%2) の外傷へ縫合をはじめた + あなたは %1 (%2) の外傷へ縫合を始めた 나는 %1(%2) 상처로부터 봉합을 시작했다 你正开始对 %1 (%2) 缝合伤口中 你正開始對 %1 (%2) 縫合傷口中 - + Stitching Наложение швов Suturando Nähen - Sutures + Suture Szycie Összevarrás Suturando @@ -3075,7 +3206,7 @@ 缝合中 縫合中 - + You treat the airway of %1 Вы интубируете раненого %1 Estás intubando a %1 @@ -3091,7 +3222,7 @@ 你治疗 %1 的呼吸道 你治療 %1 的呼吸道 - + Airway Дыхательные пути Vías aéreas @@ -3107,7 +3238,7 @@ 呼吸道 呼吸道 - + %1 is treating your airway %1 проводит вам интубацию %1 traite vos voies respiratoires @@ -3123,7 +3254,7 @@ %1 正在治疗你的呼吸道 %1 正在治療你的呼吸道 - + Drag Ziehen Arrastrar @@ -3139,7 +3270,7 @@ 拖拉 拖拉 - + Carry Tragen Cargar @@ -3150,12 +3281,12 @@ Cipelés Carregar Trasporta - 運ぶ + 担ぐ 업다 背起 背起 - + Release Loslassen Soltar @@ -3171,7 +3302,7 @@ 放下 放下 - + Load Patient Into Patient einladen Cargar al paciente en @@ -3187,7 +3318,7 @@ 将伤者放入 將傷者放入 - + Unload Patient Patient ausladen Descargar al paciente @@ -3203,7 +3334,22 @@ 将伤者背出 將傷者背出 - + + This person (%1) is awake and cannot be loaded + Diese Person (%1) ist wach und kann nicht verladen werden + Ta osoba (%1) jest przytomna i nie może zostać załadowana + Esta persona (%1) está despierto y no puede ser cargado + Боец (%1) в сознании и не может быть погружен + Esta pessoa (%1) está acordada e não pode ser carregada + Tato osoba (%1) je vzhůru a nemůže být naložena + Questa persona (%1) è sveglia e non può essere caricata. + %1 est conscient et ne peut être embarqué. + 患者 (%1) は意識があり、積み込めない + 이 사람 (%1) 은(는) 의식이 있어 태우지 못합니다 + 此人(%1)是清醒且不能被装载 + 此人(%1)是清醒且不能被裝載 + + %1<br/>loaded into<br/>%2 %1<br/>cargado en<br/>%2 %1<br/>chargé dans<br/>%2 @@ -3219,7 +3365,23 @@ %1<br/>裝載至<br/>%2 %1<br/>装载至<br/>%2 - + + Unloaded<br/>%1 from<br/>%2 + %1<br/>von<br/>%2 abgeladen + Descargado/a<br/>%1 de<br/>%2 + Déchargé<br/>%1 de<br/>%2 + %1<br/>rozładowano z<br/>%2 + %1<br/>vyloženo z<br/>%2 + %1<br/>descarregado de<br/>%2 + Hai scaricato<br/>%1 da<br/>%2 + 1%<br/>kirakodva ebből:<br/>%2 + %1<br/>разгружен из<br/>%2 + <br/>%1が<br/>%2から降ろされました + %1<br/>는<br/>%2 에서 내려짐 + 從<br/>%2卸載<br/>%1 + 从<br/>%2卸载<br/>%1 + + Place body in bodybag Colocar cuerpo en bolsa para cadáveres Поместить тело в мешок для трупов @@ -3235,7 +3397,7 @@ 将尸体放入尸袋 將屍體放入屍袋 - + Placing body in bodybag... Colocando cuerpo en bolsa para cadáveres... Упаковка тела... @@ -3251,7 +3413,7 @@ 将尸体放入尸袋中... 將屍體放入屍袋中... - + %1 has bandaged patient %1 has vendado al paciente %1 перевязал пациента @@ -3267,7 +3429,7 @@ %1 已包扎伤者 %1 已包紮傷者 - + %1 performed CPR %1 wykonał cykl RKO %1 provádí CPR @@ -3282,7 +3444,7 @@ %1 已执行心肺复苏术 %1 已執行心肺復甦術 - + %1 used %2 %1 usó %2 %1 benutzt %2 @@ -3293,18 +3455,18 @@ %1 ha usato %2 %1 usou %2 %1 použil %2 - %1 は %2 をつかった + %1 は %2 を使った %1 (이)가 %2 을 썼다 %1 已使用 %2 %1 已使用 %2 - + %1 has given an IV %1 провёл переливание %1 ha puesto una IV %1 hat eine Infusion verabreicht %1 podał IV - %1 a plaçé une IV + %1 a effectué une IV %1 infúziót adott %1 ha somministrato una EV %1 aplicou um intravenoso @@ -3314,13 +3476,13 @@ %1 已经给予静脉注射液 %1 已經給予靜脈注射液 - + %1 applied a tourniquet %1 aplicado torniquete %1 наложил жгут %1 hat ein Tourniquet angelegt %1 założył stazę - %1 a plaçé un garrot + %1 a posé un garrot %1 felhelyezett egy érszorítót %1 ha applicato un laccio emostatico %1 aplicou um torniquete @@ -3330,7 +3492,13 @@ %1 已经绑上止血带 %1 已經綁上止血帶 - + + %1 applied a splint + %1 наложил Шина + %1 a posé un attelle + %1 aplicou uma Tala + + %1 used Personal Aid Kit %1 hat das eigene Erste-Hilfe-Set verwendet %1 użył apteczki @@ -3339,13 +3507,13 @@ %1 использовал аптечку %1 ha usato Kit Pronto Soccorso Personale %1 usó Kit de Primeros Auxilios - %1 a utilisé une trousse - %1 は応急処置キットをつかった + %1 a utilisé une trousse sanitaire + %1 は応急処置キットを使った %1 (이)가 개인응급키트를 사용했다 %1 已使用了个人急救包 %1 已使用了個人急救包 - + Heavily wounded Schwer verwundet: Ciężko ranny @@ -3361,7 +3529,7 @@ 重伤 重傷 - + Lightly wounded Leicht verwundet: Lekko ranny @@ -3377,7 +3545,7 @@ 轻伤 輕傷 - + Very lightly wounded Sehr leicht verwundet: B. lekko ranny @@ -3393,7 +3561,7 @@ 小伤 小傷 - + Heal fully bandaged hitpoints Lecz w pełni zabandażowane hitpointy Curar miembros totalmente vendados @@ -3401,7 +3569,7 @@ Curar hitpoints totalmente enfaixados Heal fully bandaged hitpoints Cura hitpoints completamente bendati - Soigner les plaies entièrement bandées + Guérir les plaies entièrement bandées Heilt vollständig bandagierte Trefferpunkte 包帯は体力を完全に回復する 붕대를 감은후 체력을 회복함 @@ -3424,12 +3592,12 @@ 治疗中... 治療中... - + Removing Tourniquet... Tourniquet entfernen... Zdejmowanie stazy... Quitando torniquete... - Retire le garrot... + Retrait du garrot... Removendo torniquete... Érszorító eltávolítása... Sundavám škrtidlo... @@ -3440,96 +3608,7 @@ 移除军用止血带中... 移除軍用止血帶中... - - Convert vanilla items - - - Enables or disables whether vanilla medical items are converted to ACE medical items or just removed - - - Just remove vanilla medical - - - Locations PAK - Место использования аптечки - Ograniczenie apteczek osobistych - Ubicaciones del EPA - Orte für Erste-Hilfe-Set - Oblast k použití PAK - Localizações do KPS - Lieu d'utilisation da trousse sanitaire - Elsősegélycsomag helyek - Locazioni Kit Pronto Soccorso - 応急処置キットを使う場所 - 개인응급키트 사용 장소 - 个人急救包使用地点 - 個人急救包使用地點 - - - Remove Surgical Kit (Adv) - Удалять хирургический набор (усл.) - Usuń zestaw chirurgiczny po użyciu - Eliminar equipo quirúrgico (Avanzado) - Entferne Operationskasten (erweitert) - Odebrat chirurgickou soupravu (Pokr.) - Remover kit cirúrgico (avançado) - Consommer les trousses chirurgicales (Av.) - Sebészkészlet (Fejlett) eltávolítása - Rimuovi Kit Chirurgico (Avanzato) - 縫合キットを削除 (アド) - 봉합키트 제거 (고급) - 在使用后删除手术包 (进阶伤口) - 在使用後刪除手術包 (進階傷口) - - - Should Surgical kit be removed on usage? - Нужно ли удалять хирургический набор после использования? - Czy zestaw chirurgiczny powinien zniknąć z ekwipunku po jego użyciu? - Eliminar el equipo quirúrgico después del uso - Entferne Operationskästen bei Verwendung? - Odebrat chirurgickou soupravu po použití? - Deve o kit cirúrgico ser removido após o uso? - La trousse chirurgicale doit être consommée à l'utilisation? - Eltávolítódjon a sebészkészlet használatkor? - Il Kit Chirurgico dev'essere rimosso dopo l'uso? - 縫合キットを使った後に削除しますか? - 봉합키트를 사용하고 나서 제거합니까? - 手术包会在使用后被删除吗? - 手術包會在使用後被刪除嗎? - - - Allow Surgical Kit (Adv) - Хирургический набор может использоваться (усл.) - Ustawienia zestawu chirurgicznego - Permitir equipo quirúrgico (Avanzado) - Erlaube Operationskasten - Povolit chirurgickou soupravu (Pokr.) - Permite kit cirúrgico (avançado) - Permettre les trousses chirurgicales (Avancé) - Sebészkészlet (Fejlett) engedélyezése - Permetti Kit Chirurgico (Avanzato) - 縫合キットの許可 (アド) - 봉합키트 활성화 (고급) - 允许使用手术包 (进阶伤口) - 允許使用手術包 (進階傷口) - - - Who can use the Surgical Kit? - Кто может использовать хирургический набор? - Kto może skorzystać z zestawu chirurgicznego w celu zszycia ran? - ¿Quién puede utilizar el equipo quirúrgico? - Wer kann den Operationskasten verwenden? - Kdo může použít chirurgickou soupravu? - Quem pode usar o kit cirúrgico? - Qui peut utiliser les trousses chirurgicales? - Ki használhatja a sebészkészletet? - Chi può usare il Kit Chirurgico? - だれでも縫合キットを使えるようにしますか? - 어느 인원이 봉합키트를 사용할 수 있습니까? - 谁能够使用手术包? - 誰能夠使用手術包? - - + There is no tourniquet on this body part! An diesem Körperteil befindet sich kein Tourniquet! Na tej części ciała nie ma stazy! @@ -3544,60 +3623,28 @@ 这部位没有止血带! 這部位沒有止血帶! - + When can the PAK be used? Wann kann das Erste-Hilfe-Set verwendet werden? Kdy může být použita osobní lékárnička? ¿Cuando se puede utilizar el Equipo de primeros auxilios? - Quand peut être utilisé la trousse sanitaire? + Quand peut être utilisée la trousse sanitaire ? Po spełnieniu jakich warunków apteczka osobista może zostać zastosowana na pacjencie? Mikor lehet az elsősegélycsomagot használni? Onde o kit de primeiros socorros pode ser utilizado? - Когда может использоваться аптечка? + Где может использоваться аптечка? Quando può essere usato il Kit Pronto Soccorso? どこでも応急処置キットを使えるようにしますか? 언제 개인응급키트를 사용할 수 있습니까? 何时可以使用个人急救包? 何時可以使用個人急救包? - - Locations Surgical Kit (Adv) - Место использования хирургического набора (усл.) - Ograniczenie zestawu chirurgicznego - Ubicaciones del equipo quirúrgico (Avanzado) - Orte für Operationskästen (erweitert) - Lokace chirurgické soupravy (Pokr.) - Localizações do kit cirúrgico (avançado) - Lieu d'utilisation des trousses chirurgicales - Sebészkészlet (Fejlett) helyei - Località Kit Chirurgico (Avanzato) - 縫合キットをつかう場所 (アド) - 봉합키트 사용 장소 (고급) - 手术包使用地点 (进阶伤口) - 手術包使用地點 (進階傷口) - - - Where can the Surgical Kit be used? - Где может использоваться хирургический набор? - Gdzie można korzystać z zestawu chirurgicznego? - Dónde se puede utilizar el equipo quirúrgico - Wo kann der Operationskasten verwendet werden? - Kde může být použita chirurgická souprava? - Onde o kit cirúrgico pode ser utilizado? - Où peut être utilisé les trousses chirurgicales? - Hol lehet a sebészkészletet használni? - Dove può essere usato il Kit Chirurgico? - どこでも縫合キットを使えるようにしますか? - 어디에서 봉합키트를 사용할 수 있게 합니까? - 定义手术包可被使用的地方? - 定義手術包可被使用的地方? - - + Condition Surgical Kit (Adv) Beding. für d. Operationskasten (erw.) Podmínka chirurgické soupravy (Pokr.) Condición de equipo quirúrgico (Av) - Conditions d'utilisation de la trousse chirurgicale (Av.) + Conditions d'utilisation de la trousse chirurgicale Warunek zestawu chirurgicznego Sebészkészlet állapot Condição do Kit Cirúrgico (Avançado) @@ -3608,44 +3655,28 @@ 使用手术包的条件 (进阶伤口) 使用手術包的條件 (進階傷口) - + When can the Surgical Kit be used? Wann kann der Operationskasten verwendet werden? Kde může být použita chirurgická souprava? ¿Cuando se puede utilizar el equipo quirúrgico? - Quand peut être utilisé la trousse chirurgicale + Quand peut être utilisée la trousse chirurgicale ? Po spełnieniu jakich warunków zestaw chirurgiczny może zostać zastosowany na pacjencie? Mikor lehet a sebészkészletet használni? Onde o kit cirúrgico pode ser utilizado? - Когда может использоваться хирургический набор? + Где может использоваться хирургический набор? Quando può essere usato il Kit Chirurgico? いつでも縫合キットを使えるようにしますか? 언제 봉합키트를 사용할 수 있습니까? 何时可以使用手术工具包? 何時可以使用手術工具包? - - Where can the PAK be used? - Где может использоваться аптечка? - Gdzie można korzystać z apteczek osobistych? - ¿Dónde se puede utilizar el equipo de primeros auxilios? - Wo kann das Erste-Hilfe-Set verwendet werden? - Kde může být použita osobní lékárnička (PAK)? - Onde o kit de primeiros socorros pode ser utilizado? - Où la trousse sanitaire peut être utilisée ? - Hol lehet az elsősegélycsomagot használni? - Dove può essere usato il Kit Pronto Soccorso? - どこでも応急処置キットを使えるようにしますか? - 어디에서 개인응급키트를 사용할 수 있습니까? - 在哪里可以使用个人急救包? - 在哪裡可以使用個人急救包? - - + Condition PAK Bedingungen für d. Erste-Hilfe-Set Podmínky pro použití osobní lékárničky Condición EPA - Condition d'utilisation de la trousse sanitaire + Conditions d'utilisation de la trousse sanitaire Warunek apteczek Elsősegélycsomag állapot Condição do KPS @@ -3656,5 +3687,23 @@ 个人急救包使用条件 個人急救包使用條件 + + Clear Trauma After Bandage + + + Heal fully bandaged hitpoints + Lecz w pełni zabandażowane hitpointy + Curar miembros totalmente vendados + Исцелять полностью перебинтованные части тела + Curar pontos de vida totalmente enfaixados + Heal fully bandaged hitpoints + Cura hitpoints completamente bendati + Soigner les plaies entièrement bandées + Heilt vollständig bandagierte Trefferpunkte + 包帯は体力を完全に回復する + 붕대를 감은후 체력을 회복함 + 完全医疗包扎的部位至痊愈 + 完全醫療包紮的部位至痊癒 + diff --git a/addons/medical_treatment/ui/items/adenosine_x_ca.paa b/addons/medical_treatment/ui/adenosine_ca.paa similarity index 100% rename from addons/medical_treatment/ui/items/adenosine_x_ca.paa rename to addons/medical_treatment/ui/adenosine_ca.paa diff --git a/addons/medical_treatment/ui/items/atropine_x_ca.paa b/addons/medical_treatment/ui/atropine_ca.paa similarity index 100% rename from addons/medical_treatment/ui/items/atropine_x_ca.paa rename to addons/medical_treatment/ui/atropine_ca.paa diff --git a/addons/medical_treatment/ui/items/bloodiv_x_ca.paa b/addons/medical_treatment/ui/bloodiv_ca.paa similarity index 100% rename from addons/medical_treatment/ui/items/bloodiv_x_ca.paa rename to addons/medical_treatment/ui/bloodiv_ca.paa diff --git a/addons/medical_treatment/ui/items/bodybag_x_ca.paa b/addons/medical_treatment/ui/bodybag_ca.paa similarity index 100% rename from addons/medical_treatment/ui/items/bodybag_x_ca.paa rename to addons/medical_treatment/ui/bodybag_ca.paa diff --git a/addons/medical_treatment/ui/items/elasticbandage_x_ca.paa b/addons/medical_treatment/ui/elasticbandage_ca.paa similarity index 100% rename from addons/medical_treatment/ui/items/elasticbandage_x_ca.paa rename to addons/medical_treatment/ui/elasticbandage_ca.paa diff --git a/addons/medical_treatment/ui/items/epinephrine_x_ca.paa b/addons/medical_treatment/ui/epinephrine_ca.paa similarity index 100% rename from addons/medical_treatment/ui/items/epinephrine_x_ca.paa rename to addons/medical_treatment/ui/epinephrine_ca.paa diff --git a/addons/medical_treatment/ui/items/fielddressing_x_ca.paa b/addons/medical_treatment/ui/fielddressing_ca.paa similarity index 100% rename from addons/medical_treatment/ui/items/fielddressing_x_ca.paa rename to addons/medical_treatment/ui/fielddressing_ca.paa diff --git a/addons/medical_treatment/ui/items/morphine_x_ca.paa b/addons/medical_treatment/ui/morphine_ca.paa similarity index 100% rename from addons/medical_treatment/ui/items/morphine_x_ca.paa rename to addons/medical_treatment/ui/morphine_ca.paa diff --git a/addons/medical_treatment/ui/items/packingbandage_x_ca.paa b/addons/medical_treatment/ui/packingbandage_ca.paa similarity index 100% rename from addons/medical_treatment/ui/items/packingbandage_x_ca.paa rename to addons/medical_treatment/ui/packingbandage_ca.paa diff --git a/addons/medical_treatment/ui/items/personal_aid_kit_x_ca.paa b/addons/medical_treatment/ui/personal_aid_kit_ca.paa similarity index 100% rename from addons/medical_treatment/ui/items/personal_aid_kit_x_ca.paa rename to addons/medical_treatment/ui/personal_aid_kit_ca.paa diff --git a/addons/medical_treatment/ui/items/plasmaiv_x_ca.paa b/addons/medical_treatment/ui/plasmaiv_ca.paa similarity index 100% rename from addons/medical_treatment/ui/items/plasmaiv_x_ca.paa rename to addons/medical_treatment/ui/plasmaiv_ca.paa diff --git a/addons/medical_treatment/ui/items/quickclot_x_ca.paa b/addons/medical_treatment/ui/quickclot_ca.paa similarity index 100% rename from addons/medical_treatment/ui/items/quickclot_x_ca.paa rename to addons/medical_treatment/ui/quickclot_ca.paa diff --git a/addons/medical_treatment/ui/items/salineiv_x_ca.paa b/addons/medical_treatment/ui/salineiv_ca.paa similarity index 100% rename from addons/medical_treatment/ui/items/salineiv_x_ca.paa rename to addons/medical_treatment/ui/salineiv_ca.paa diff --git a/addons/medical_treatment/ui/splint_ca.paa b/addons/medical_treatment/ui/splint_ca.paa new file mode 100644 index 0000000000..ea09181ef0 Binary files /dev/null and b/addons/medical_treatment/ui/splint_ca.paa differ diff --git a/addons/medical_treatment/ui/items/surgicalkit_x_ca.paa b/addons/medical_treatment/ui/surgicalkit_ca.paa similarity index 100% rename from addons/medical_treatment/ui/items/surgicalkit_x_ca.paa rename to addons/medical_treatment/ui/surgicalkit_ca.paa diff --git a/addons/medical_treatment/ui/items/tourniquet_x_ca.paa b/addons/medical_treatment/ui/tourniquet_ca.paa similarity index 100% rename from addons/medical_treatment/ui/items/tourniquet_x_ca.paa rename to addons/medical_treatment/ui/tourniquet_ca.paa diff --git a/addons/medical_vitals/XEH_preInit.sqf b/addons/medical_vitals/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/medical_vitals/XEH_preInit.sqf +++ b/addons/medical_vitals/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/medical_vitals/functions/fnc_handleUnitVitals.sqf b/addons/medical_vitals/functions/fnc_handleUnitVitals.sqf index 64c8b0cd4c..5fe474ad38 100644 --- a/addons/medical_vitals/functions/fnc_handleUnitVitals.sqf +++ b/addons/medical_vitals/functions/fnc_handleUnitVitals.sqf @@ -113,6 +113,7 @@ switch (true) do { TRACE_3("BloodVolume Fatal",_unit,BLOOD_VOLUME_FATAL,_bloodVolume); [QEGVAR(medical,Bleedout), _unit] call CBA_fnc_localEvent; }; + case (IN_CRDC_ARRST(_unit)): {}; // if in cardiac arrest just break now to avoid throwing unneeded events case (_hemorrhage == 4): { TRACE_3("Class IV Hemorrhage",_unit,_hemorrhage,_bloodVolume); [QEGVAR(medical,FatalVitals), _unit] call CBA_fnc_localEvent; diff --git a/addons/medical_vitals/functions/fnc_updateHeartRate.sqf b/addons/medical_vitals/functions/fnc_updateHeartRate.sqf index b7abb89a24..4da8519077 100644 --- a/addons/medical_vitals/functions/fnc_updateHeartRate.sqf +++ b/addons/medical_vitals/functions/fnc_updateHeartRate.sqf @@ -22,7 +22,15 @@ params ["_unit", "_hrTargetAdjustment", "_deltaT", "_syncValue"]; private _heartRate = GET_HEART_RATE(_unit); -if !IN_CRDC_ARRST(_unit) then { +if IN_CRDC_ARRST(_unit) then { + if (alive (_unit getVariable [QEGVAR(medical,CPR_provider), objNull])) then { + if (_heartRate == 0) then { _syncValue = true }; // always sync on large change + _heartRate = random [25, 30, 35]; + } else { + if (_heartRate != 0) then { _syncValue = true }; // always sync on large change + _heartRate = 0 + }; +} else { private _hrChange = 0; private _targetHR = 0; private _bloodVolume = GET_BLOOD_VOLUME(_unit); @@ -32,12 +40,12 @@ if !IN_CRDC_ARRST(_unit) then { private _painLevel = GET_PAIN_PERCEIVED(_unit); private _targetBP = 107; - if (_bloodVolume < BLOOD_VOLUME_CLASS_3_HEMORRHAGE) then { + if (_bloodVolume < BLOOD_VOLUME_CLASS_2_HEMORRHAGE) then { _targetBP = _targetBP * (_bloodVolume / DEFAULT_BLOOD_VOLUME); }; _targetHR = DEFAULT_HEART_RATE; - if (_bloodVolume < BLOOD_VOLUME_CLASS_2_HEMORRHAGE) then { + if (_bloodVolume < BLOOD_VOLUME_CLASS_3_HEMORRHAGE) then { _targetHR = _heartRate * (_targetBP / (45 max _meanBP)); }; if (_painLevel > 0.2) then { diff --git a/addons/microdagr/stringtable.xml b/addons/microdagr/stringtable.xml index d2808fac0a..441275728c 100644 --- a/addons/microdagr/stringtable.xml +++ b/addons/microdagr/stringtable.xml @@ -27,7 +27,7 @@ MicroDAGR pokročílá GPS příjímač MicroDAGR fejlett GPS vevőegység Ricevitore GPS avanzato MicroDAGR - Recepitor GPS avançado MicroDAGR + Receptor GPS avançado MicroDAGR MicroDAGR は改良された GPS 受信機です MicroDAGR 고급 위성항법 수신기 微型军用高级防御GPS接收器 @@ -139,7 +139,7 @@ Napiš souřadnice: Add meg a rácskoordinátákat: Introduci griglia coordinate: - Digite as Ccords. do Grid + Digite as Coords. do Grid 座標を入力: 输入网格座标: 輸入網格座標: @@ -503,6 +503,8 @@ MicroDAGR - Precisione del Waypoint MicroDAGR - ウェイポイントの精度 MicroDAGR - Precyzja PT + MicroDAGR - Точность маршрутных точек + MicroDAGR - Precisão de Waypoint Controls how precise the waypointdistance can be displayed @@ -510,6 +512,8 @@ Controlla quanto precisamente può essere visualizzato il waypoint a distanza 表示されるウェイポイントの精度を設定します Kontroluje jak precyzyjnie może być wyświetlany dystans PT + Управляет точностью отображения расстояний маршрутных точек + Controla o quão preciso pode exibir o waypoint de distância 100m @@ -517,6 +521,8 @@ 100m 100m 100m + 100 м + 100m 10m @@ -524,6 +530,8 @@ 10m 10m 10m + 10 м + 10m 1m @@ -531,6 +539,8 @@ 1m 1m 1m + 1 м + 1m Controls how much data is filled on the microDAGR items. Less data restricts the map view to show less on the minimap. diff --git a/addons/minedetector/stringtable.xml b/addons/minedetector/stringtable.xml index 72f389813f..c7b0a446eb 100644 --- a/addons/minedetector/stringtable.xml +++ b/addons/minedetector/stringtable.xml @@ -13,6 +13,7 @@ Metal detector 金属探测器 金屬探測器 + Detector de Metais Metal detector @@ -26,6 +27,7 @@ Metal detector 金属探测器 金屬探測器 + Detector de Metais Activate @@ -39,6 +41,7 @@ Attiva 启用探测器 啟用探測器 + Ativar Deactivate @@ -52,6 +55,7 @@ Disattiva 停用探测器 停用探測器 + Desativar Connect Headphones @@ -65,6 +69,7 @@ Connetti Auricolari 连接耳机 連接耳機 + Conectar fones de ouvido Disconnect Headphones @@ -78,6 +83,7 @@ Disconnetti Auricolari 断开耳机 斷開耳機 + Desconectar fones de ouvido Headphones Connected @@ -91,6 +97,7 @@ Auricolari Connessi 已连接耳机 已連接耳機 + Fones de ouvido conectados Headphones Disconnected @@ -104,6 +111,7 @@ Auricolari Disconnessi 已断开耳机 已斷開耳機 + Fones de ouvido conectados diff --git a/addons/missileguidance/functions/fnc_checkLos.sqf b/addons/missileguidance/functions/fnc_checkLos.sqf index 205ff3d4ef..edc8b5ab19 100644 --- a/addons/missileguidance/functions/fnc_checkLos.sqf +++ b/addons/missileguidance/functions/fnc_checkLos.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" /* * Author: jaynus - * Returns whether the seeker object can see the target position with lineIntersect + * Returns whether the seeker object can see the target position with checkVisibility * * Arguments: * 0: Seeker @@ -18,22 +18,5 @@ params ["_seeker", "_target"]; -if ((isNil "_seeker") || {isNil "_target"}) exitWith { - ERROR_2("nil",_seeker,_target); - false -}; - -private _targetPos = getPosASL _target; -private _targetAimPos = aimPos _target; -private _seekerPos = getPosASL _seeker; -private _return = true; - -if (!((terrainIntersectASL [_seekerPos, _targetPos]) && {terrainIntersectASL [_seekerPos, _targetAimPos]})) then { - if (lineIntersects [_seekerPos, _targetPos, _seeker, _target]) then { - _return = false; - }; -} else { - _return = false; -}; - -_return; +private _visibility = [_seeker, "VIEW", _target] checkVisibility [getPosASL _seeker, aimPos _target]; +_visibility > 0.001 diff --git a/addons/missileguidance/functions/fnc_guidancePFH.sqf b/addons/missileguidance/functions/fnc_guidancePFH.sqf index 8196de8057..e218e27e54 100644 --- a/addons/missileguidance/functions/fnc_guidancePFH.sqf +++ b/addons/missileguidance/functions/fnc_guidancePFH.sqf @@ -55,7 +55,8 @@ private _seekerTargetPos = [[0,0,0], _args, _seekerStateParams, _lastKnownPosSta private _profileAdjustedTargetPos = [_seekerTargetPos, _args, _attackProfileStateParams] call FUNC(doAttackProfile); // If we have no seeker target, then do not change anything -if (!(_profileAdjustedTargetPos isEqualTo [0,0,0])) then { +// If there is no deflection on the missile, this cannot change and therefore is redundant. Avoid calculations for missiles without any deflection +if ((_minDeflection != 0 || {_maxDeflection != 0}) && {!(_profileAdjustedTargetPos isEqualTo [0,0,0])}) then { private _targetVector = _projectilePos vectorFromTo _profileAdjustedTargetPos; private _adjustVector = _targetVector vectorDiff (vectorDir _projectile); diff --git a/addons/missileguidance/functions/fnc_onFired.sqf b/addons/missileguidance/functions/fnc_onFired.sqf index 0e690c79f4..b77911e979 100644 --- a/addons/missileguidance/functions/fnc_onFired.sqf +++ b/addons/missileguidance/functions/fnc_onFired.sqf @@ -112,19 +112,30 @@ private _args = [_this, [ getNumber ( _config >> "seekerAngle" ), getNumber ( _config >> "seekerAccuracy" ), - getNumber ( _config >> "seekerMaxRange" ) + getNumber ( _config >> "seekerMaxRange" ), + getNumber ( _config >> "seekerMinRange" ) ], [ diag_tickTime, [], [], _lastKnownPosState] ]; - -// Run the "onFired" function passing the full guidance args array -private _onFiredFunc = getText (_config >> "onFired"); +private _onFiredFunc = getText (configFile >> QGVAR(SeekerTypes) >> _seekerType >> "onFired"); TRACE_1("",_onFiredFunc); if (_onFiredFunc != "") then { _args call (missionNamespace getVariable _onFiredFunc); }; +_onFiredFunc = getText (configFile >> QGVAR(AttackProfiles) >> _attackProfile >> "onFired"); +TRACE_1("",_onFiredFunc); +if (_onFiredFunc != "") then { + _args call (missionNamespace getVariable _onFiredFunc); +}; + +// Run the "onFired" function passing the full guidance args array +_onFiredFunc = getText (_config >> "onFired"); +TRACE_1("",_onFiredFunc); +if (_onFiredFunc != "") then { + _args call (missionNamespace getVariable _onFiredFunc); +}; // Reverse: // _args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams"]; @@ -134,24 +145,6 @@ if (_onFiredFunc != "") then { // _stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState"]; // _seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange"]; - -// Hand off to the guiding unit. We just use local player so local PFH fires for now -// Laser code needs to give us a shooter for LOBL, or the seeker unit needs to be able to shift locality -// Based on its homing laser -// Lasers need to be handled in a special LOAL/LOBL case - -//if (isPlayer _shooter) then { -// private _guidingUnit = ACE_player; -// -// if (local _guidingUnit) then { -// [FUNC(guidancePFH), 0, _args ] call CBA_fnc_addPerFrameHandler; -// } else { -// [QGVAR(handoff), [_guidingUnit, _args] ] call FUNC(doHandoff); -// }; -//} else { - // [FUNC(guidancePFH), 0, _args ] call CBA_fnc_addPerFrameHandler; -//}; - [FUNC(guidancePFH), 0, _args ] call CBA_fnc_addPerFrameHandler; diff --git a/addons/missileguidance/stringtable.xml b/addons/missileguidance/stringtable.xml index 1758dea3e3..06590e62cc 100644 --- a/addons/missileguidance/stringtable.xml +++ b/addons/missileguidance/stringtable.xml @@ -9,7 +9,7 @@ Erweitertes Raketenlenksystem Pokročilé řízení střel Guida missili avanzata - Avançado Missile Guidance + Orientação avançada de Míssil Fejlett rakétairányító Продвинутое наведение ракет 高度なミサイルの誘導 diff --git a/addons/missionmodules/stringtable.xml b/addons/missionmodules/stringtable.xml index cb28cb3d7e..4c81780a20 100644 --- a/addons/missionmodules/stringtable.xml +++ b/addons/missionmodules/stringtable.xml @@ -7,7 +7,7 @@ Módulo de misiones ACE ACE-Missionsmodule ACE Moduly mise - Módulo de missões ACE + ACE Módulo de missões ACE module de mission ACE küldetési modulok Модули миссий ACE diff --git a/addons/mk6mortar/CfgVehicles.hpp b/addons/mk6mortar/CfgVehicles.hpp index 4a5d420f5c..41e45abf35 100644 --- a/addons/mk6mortar/CfgVehicles.hpp +++ b/addons/mk6mortar/CfgVehicles.hpp @@ -24,9 +24,12 @@ class CfgVehicles { class Turrets: Turrets { class MainTurret: MainTurret {}; }; - class ACE_Actions; }; class Mortar_01_base_F: StaticMortar { + class ace_csw { + proxyWeapon = QFUNC(csw_getProxyWeapon); + magazineLocation = "_target selectionPosition 'usti hlavne'"; + }; class Turrets: Turrets { class MainTurret: MainTurret { turretInfoType = "ACE_Mk6_RscWeaponRangeArtillery"; @@ -34,54 +37,6 @@ class CfgVehicles { discreteDistanceInitIndex = 0; }; }; - class ACE_Actions: ACE_Actions { - class GVAR(unloadMagazine) { - displayName = CSTRING(unloadMortar); - distance = 2; - condition = QUOTE(_this call FUNC(canUnloadMagazine)); - statement = QUOTE([ARR_3(_target,_player,5)] call FUNC(unloadMagazineTimer)); - icon = ""; - selection = "usti hlavne"; - }; - class GVAR(LoadActions) { - displayName = CSTRING(loadMortar); - distance = 2; - condition = QUOTE([ARR_2(_target,_player)] call FUNC(canLoadMagazine)); - statement = ""; - icon = ""; - selection = "usti hlavne"; - class GVAR(loadMagazine_HE_Guided) { - displayName = CSTRING(loadMagazine_HE_Guided); - condition = QUOTE([ARR_3(_target,_player,'ACE_1Rnd_82mm_Mo_HE_Guided')] call FUNC(canLoadMagazine)); - statement = QUOTE([ARR_4(_target,_player,8,'ACE_1Rnd_82mm_Mo_HE_Guided')] call FUNC(loadMagazineTimer)); - icon = ""; - }; - class GVAR(loadMagazine_HE_LaserGuided) { - displayName = CSTRING(loadMagazine_HE_LaserGuided); - condition = QUOTE([ARR_3(_target,_player,'ACE_1Rnd_82mm_Mo_HE_LaserGuided')] call FUNC(canLoadMagazine)); - statement = QUOTE([ARR_4(_target,_player,8,'ACE_1Rnd_82mm_Mo_HE_LaserGuided')] call FUNC(loadMagazineTimer)); - icon = ""; - }; - class GVAR(loadMagazine_Illum) { - displayName = CSTRING(loadMagazine_Illum); - condition = QUOTE([ARR_3(_target,_player,'ACE_1Rnd_82mm_Mo_Illum')] call FUNC(canLoadMagazine)); - statement = QUOTE([ARR_4(_target,_player,5,'ACE_1Rnd_82mm_Mo_Illum')] call FUNC(loadMagazineTimer)); - icon = ""; - }; - class GVAR(loadMagazine_Smoke) { - displayName = CSTRING(loadMagazine_Smoke); - condition = QUOTE([ARR_3(_target,_player,'ACE_1Rnd_82mm_Mo_Smoke')] call FUNC(canLoadMagazine)); - statement = QUOTE([ARR_4(_target,_player,2.5,'ACE_1Rnd_82mm_Mo_Smoke')] call FUNC(loadMagazineTimer)); - icon = ""; - }; - class GVAR(loadMagazine_HE) { - displayName = CSTRING(loadMagazine_HE); - condition = QUOTE([ARR_3(_target,_player,'ACE_1Rnd_82mm_Mo_HE')] call FUNC(canLoadMagazine)); - statement = QUOTE([ARR_4(_target,_player,2.5,'ACE_1Rnd_82mm_Mo_HE')] call FUNC(loadMagazineTimer)); - icon = ""; - }; - }; - }; class ACE_SelfActions { class GVAR(toggleMils) { displayName = "Toggle MILS"; diff --git a/addons/mk6mortar/XEH_PREP.hpp b/addons/mk6mortar/XEH_PREP.hpp index 600fc0707f..03d6bd6051 100644 --- a/addons/mk6mortar/XEH_PREP.hpp +++ b/addons/mk6mortar/XEH_PREP.hpp @@ -5,19 +5,14 @@ PREP(dev_simulateCalcRangeTableLine); PREP(dev_simulateFindSolution); PREP(dev_simulateShot); -PREP(canLoadMagazine); -PREP(canUnloadMagazine); +PREP(csw_getProxyWeapon); + PREP(handleFired); PREP(handlePlayerVehicleChanged); -PREP(loadMagazine); -PREP(loadMagazineTimer); PREP(moduleInit); -PREP(mortarInit); PREP(rangeTableCanUse); PREP(rangeTableOpen); PREP(rangeTablePageChange); PREP(rangeTablePreCalculatedValues); PREP(toggleMils); PREP(turretDisplayLoaded); -PREP(unloadMagazine); -PREP(unloadMagazineTimer); diff --git a/addons/mk6mortar/XEH_postInit.sqf b/addons/mk6mortar/XEH_postInit.sqf index e3169b6dba..338f859767 100644 --- a/addons/mk6mortar/XEH_postInit.sqf +++ b/addons/mk6mortar/XEH_postInit.sqf @@ -1,22 +1,5 @@ #include "script_component.hpp" -[QGVAR(addMagazine), { - params ["_static", "_magazine"]; - _static addMagazineTurret [_magazine,[0]]; -}] call CBA_fnc_addEventHandler; - -[QGVAR(removeMagazine), { - params ["_static", "_magazine"]; - _static removeMagazineTurret [_magazine,[0]]; -}] call CBA_fnc_addEventHandler; - -[QGVAR(setAmmo), { - params ["_static", "_magazine","_ammoCount"]; - _static setMagazineTurretAmmo [_magazine, _ammoCount, [0]]; -}] call CBA_fnc_addEventHandler; - -["ace_initMortar", {_this call FUNC(mortarInit);}] call CBA_fnc_addEventHandler; - if (hasInterface) then { ["ace_infoDisplayChanged", FUNC(turretDisplayLoaded)] call CBA_fnc_addEventHandler; }; @@ -25,17 +8,4 @@ if (hasInterface) then { TRACE_1("ace_settingsInitialized",GVAR(useAmmoHandling)); ["vehicle", FUNC(handlePlayerVehicleChanged), true] call CBA_fnc_addPlayerEventHandler; - - if (GVAR(useAmmoHandling)) then { - ["Mortar_01_base_F", "init", { - TRACE_2("mortar init",_this,(_this select 0) turretLocal [0]); - - //wait for proper turret locality change - [{ - TRACE_2("after delay",_this,(_this select 0) turretLocal [0]); - ["ace_initMortar", _this] call CBA_fnc_localEvent; - }, _this, 0.5] call CBA_fnc_waitAndExecute; - - }, true, [], true] call CBA_fnc_addClassEventHandler; - }; }] call CBA_fnc_addEventHandler; diff --git a/addons/mk6mortar/config.cpp b/addons/mk6mortar/config.cpp index f387632446..79fd043619 100644 --- a/addons/mk6mortar/config.cpp +++ b/addons/mk6mortar/config.cpp @@ -7,7 +7,7 @@ class CfgPatches { "ACE_Box_82mm_Mo_Illum","ACE_Box_82mm_Mo_Combo"}; weapons[] = {"ACE_RangeTable_82mm","ace_mortar_82mm"}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"ace_interaction"}; + requiredAddons[] = {"ace_csw"}; author = ECSTRING(common,ACETeam); authors[] = {"PabstMirror","Grey","VKing"}; url = ECSTRING(main,URL); diff --git a/addons/mk6mortar/functions/fnc_canLoadMagazine.sqf b/addons/mk6mortar/functions/fnc_canLoadMagazine.sqf deleted file mode 100644 index 67bcf4d522..0000000000 --- a/addons/mk6mortar/functions/fnc_canLoadMagazine.sqf +++ /dev/null @@ -1,52 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Grey - * Checks whether magazine can be loaded into static weapon - * - * Arguments: - * 0: static - * 1: unit - * 2: magazine class to check; if not given having any compatible magazine returns true (default: "") - * - * Return Value: - * canLoadMagazine - * - * Example: - * [_target,_player,"ACE_1Rnd_82mm_Mo_HE"] call ace_mk6mortar_fnc_canLoadMagazine - * - * Public: Yes - */ - -params ["_static","_unit",["_magazineClassOptional","",[""]]]; - -if !(alive _static && GVAR(useAmmoHandling)) exitWith {false}; -if (_static getVariable [QGVAR(inUse), false]) exitWith {false}; - -private _canLoadMagazine = false; -private _hasCompatibleMagazine = false; - -private _currentMagazine = (magazinesAllTurrets _static) select 1; -private _weapon = (_static weaponsTurret [0]) select 0; - -private _listOfMagNames = getArray(configFile >> "cfgWeapons" >> _weapon >> "magazines"); -private _count = 0; - -//If function is called with an optional string then check if player has that magzine otherwise check all magazines of the player to see if they are compatible with the static weapon -if (_magazineClassOptional != "") then { - if ([_unit,_magazineClassOptional] call EFUNC(common,hasMagazine)) then { - _hasCompatibleMagazine = true; - }; - } else { - { - if ([_unit,_x] call EFUNC(common,hasMagazine)) exitWith {_hasCompatibleMagazine = true}; - } forEach _listOfMagNames; -}; -//If static weapon has a magazine then find the ammo count -if (count (_static magazinesTurret [0]) > 0) then { - _count = _currentMagazine select 2; -}; -//If the static weapon doesn't have a magzine or a magazine with no bullets, the player has a compatible magazine and the static weapon has a barrel then you can load a magazine -if ((count (_static magazinesTurret [0]) == 0 || _count == 0) && _hasCompatibleMagazine) then { - _canLoadMagazine = true; -}; -_canLoadMagazine diff --git a/addons/mk6mortar/functions/fnc_canUnloadMagazine.sqf b/addons/mk6mortar/functions/fnc_canUnloadMagazine.sqf deleted file mode 100644 index a296d56c32..0000000000 --- a/addons/mk6mortar/functions/fnc_canUnloadMagazine.sqf +++ /dev/null @@ -1,30 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Grey - * Checks whether magazine can be unloaded from static weapon - * - * Arguments: - * 0: static - * 1: unit - * - * Return Value: - * canUnloadMagazine - * - * Example: - * [_target,_player] call ace_mk6mortar_fnc_canUnloadMagazine - * - * Public: Yes - */ - -params ["_static","_unit"]; - -if !(alive _static && GVAR(useAmmoHandling) && _static getVariable [QGVAR(initialized),false]) exitWith {false}; -if (_static getVariable [QGVAR(inUse), false]) exitWith {false}; - -private _canUnloadMagazine = false; - -private _ammoCount = ((magazinesAllTurrets _static) select 1) select 2; -if (_ammoCount > 0) then { - _canUnloadMagazine = true; -}; -_canUnloadMagazine diff --git a/addons/mk6mortar/functions/fnc_csw_getProxyWeapon.sqf b/addons/mk6mortar/functions/fnc_csw_getProxyWeapon.sqf new file mode 100644 index 0000000000..04ed2a0014 --- /dev/null +++ b/addons/mk6mortar/functions/fnc_csw_getProxyWeapon.sqf @@ -0,0 +1,68 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Compatibility With ACE_CSW (will be called by ace_csw, no dependency) + * Setting Init has finished, and this runs before csw attempts to unload weapon, should replicate functionality of mk6_fnc_mortarInit + * + * Arguments: + * 0: static + * 1: Turret + * 2: current weapon + * 3: need proxy weapon (either assembly mode is true, or weapon has been emptied and is being reloaded) + * + * Return Value: + * Proxy Weapon + * + * Example: + * [mortar, "mortar_82mm", true] call ace_mk6mortar_fnc_csw_getProxyWeapon + * + * Public: No + */ + +params ["_mortar", "_turret", "_currentWeapon", "_proxyWeaponNeeded"]; +TRACE_4("csw_getProxyWeapon",_mortar,_turret,_currentWeapon,_proxyWeaponNeeded); + +private _newWeapon = ""; + +if (_proxyWeaponNeeded || GVAR(useAmmoHandling)) then { + if (_currentWeapon != "mortar_82mm") exitWith { ERROR_2("unknown weapon [%1 - %2]",typeOf _mortar,_currentWeapon); }; + + // Replace weapon with fast reloading version + _newWeapon = "ace_mortar_82mm"; + TRACE_1("replacing weapon",_newWeapon); + + // need to convert 8rnd mags to 1rnd mags for new weapon (we need to do this so the weapon is loaded with a compatible mag) + private _magsToRemove = []; + private _convertedMags = []; + { + _x params ["_xMag", "_xTurret", "_xAmmo"]; + + if (_xTurret isEqualTo _turret) then { + private _replaceMag = switch (true) do { + case (_xMag == "8Rnd_82mm_Mo_shells"): {"ACE_1Rnd_82mm_Mo_HE"}; + case (_xMag == "8Rnd_82mm_Mo_Smoke_white"): {"ACE_1Rnd_82mm_Mo_Smoke"}; + case (_xMag == "8Rnd_82mm_Mo_Flare_white"): {"ACE_1Rnd_82mm_Mo_Illum"}; + case (_xMag == "8Rnd_82mm_Mo_guided"): {"ACE_1Rnd_82mm_Mo_HE_Guided"}; + case (_xMag == "8Rnd_82mm_Mo_LG"): {"ACE_1Rnd_82mm_Mo_HE_LaserGuided"}; + default {""}; + }; + if (_replaceMag != "") then { + _magsToRemove pushBackUnique [_xMag, _xTurret]; + if (!GVAR(useAmmoHandling)) then { + TRACE_3("replacing",_xMag,_replaceMag,_xAmmo); + for "_i" from 1 to _xAmmo do { + _convertedMags pushBack [_replaceMag, _xTurret, 1]; + }; + }; + } else { + WARNING("unknown mag %1", _xMag); + }; + }; + } forEach (magazinesAllTurrets _mortar); + + // remove orignal mags and add 1rnd versions: + { _staticWeapon removeMagazinesTurret _x; } forEach _magsToRemove; + { _mortar addMagazineTurret _x; } forEach _convertedMags; +}; + +_newWeapon diff --git a/addons/mk6mortar/functions/fnc_handleFired.sqf b/addons/mk6mortar/functions/fnc_handleFired.sqf index 02a8e51ce0..550ae05f8a 100644 --- a/addons/mk6mortar/functions/fnc_handleFired.sqf +++ b/addons/mk6mortar/functions/fnc_handleFired.sqf @@ -23,13 +23,6 @@ params ["_vehicle", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile"]; -if (GVAR(useAmmoHandling) && {_vehicle getVariable [QGVAR(initialized),false] && !(_vehicle getVariable [QGVAR(exclude),false])}) then { - // if !(_vehicle getVariable [QGVAR(exclude),false]) then { - _vehicle removeMagazineGlobal (_vehicle magazinesTurret [0] select 0); - TRACE_1("",_vehicle magazinesTurret [0]); - // }; -}; - if (!GVAR(airResistanceEnabled)) exitWith {}; // Large enough distance to not simulate any wind deflection diff --git a/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf b/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf index fd53bcf3d4..6e0b9b1794 100644 --- a/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf +++ b/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf @@ -21,20 +21,6 @@ params ["_player", "_newVehicle"]; if (isNull _newVehicle) exitWith {}; if (!(_newVehicle isKindOf "Mortar_01_base_F")) exitWith {}; -// Run magazine handling initialization if enabled -if (!(_newVehicle getVariable [QGVAR(initialized),false]) && !(_newVehicle getVariable [QGVAR(exclude),false])) then { - // Make sure that mortar init is executed after settings init - [{ - params ["_mortar"]; - if (GVAR(useAmmoHandling) && {!(_mortar getVariable [QGVAR(initialized),false]) && !(_mortar getVariable [QGVAR(exclude),false])}) then { - //wait for proper turret locality change - [{ - ["ace_initMortar", [_this], [_this]] call CBA_fnc_globalEvent; - }, _mortar, 0.05] call CBA_fnc_waitAndExecute; - }; - }, _newVehicle] call EFUNC(common,runAfterSettingsInit); -}; - private _tubeWeaponName = (weapons _newVehicle) select 0; private _fireModes = getArray (configFile >> "CfgWeapons" >> _tubeWeaponName >> "modes"); diff --git a/addons/mk6mortar/functions/fnc_loadMagazine.sqf b/addons/mk6mortar/functions/fnc_loadMagazine.sqf deleted file mode 100644 index 297fb2a969..0000000000 --- a/addons/mk6mortar/functions/fnc_loadMagazine.sqf +++ /dev/null @@ -1,62 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Grey - * Loads Magazine into static weapon - * - * Arguments: - * 0: static - * 1: unit - * 2: magazine class to load; if not given the first compatible magazine is loaded (default: "") - * - * Return Value: - * None - * - * Example: - * [_target,_player,"ACE_1Rnd_82mm_Mo_HE"] call ace_mk6mortar_fnc_loadMagazine - * - * Public: Yes - */ - -params ["_static","_unit",["_magazineClassOptional","",[""]]]; - -//If function has been called with an optional classname hten add that magazine to the static weapon. Otherwise add the compatible magazine -if(_magazineClassOptional != "") then { - _unit removeMagazine _magazineClassOptional; - [QGVAR(addMagazine), [_static, _magazineClassOptional]] call CBA_fnc_globalEvent; -} else { - //Get weapon & magazine information of static weapon - private _weapon = (_static weaponsTurret [0]) select 0; - private _currentMagazine = (magazinesAllTurrets _static) select 1; - private _currentMagazineClass = _currentMagazine select 0; - private _count = _currentMagazine select 2; - - //Check all of the players magazines to see if they are compatible with the static weapon. First magazine that is compatible is chosen - //VKing: This section ought to be double checked. - private _magazines = magazines _unit; - private _magazineDetails = magazinesDetail _unit; - private _listOfMagNames = getArray(configFile >> "cfgWeapons" >> _weapon >> "magazines"); - private _magazineClass = ""; - private _magazineClassDetails = ""; - private _roundsLeft = 0; - { - if (_x in _listOfMagNames) exitWith { - _magazineClass = _x; - _magazineClassDetails = _magazineDetails select _forEachIndex; - }; - } forEach _magazines; - //If the static weapon already has an empty magazine then remove it - if (_count == 0) then { - [QGVAR(removeMagazine), [_static, _currentMagazineClass]] call CBA_fnc_globalEvent; - }; - //Find out the ammo count of the compatible magazine found - if (_magazineClassDetails != "") then{ - private _parsed = _magazineClassDetails splitString "([]/: )"; - _parsed params ["_type", "", "", "_roundsLeftText", "_maxRoundsText"]; - _roundsLeft = parseNumber _roundsLeftText; - _magType = _type; - }; - - _unit removeMagazine _magazineClass; - [QGVAR(addMagazine), [_static, _magazineClass]] call CBA_fnc_globalEvent; - [QGVAR(setAmmo), [_static, _magazineClass,_roundsLeft], _static] call CBA_fnc_targetEvent; -}; diff --git a/addons/mk6mortar/functions/fnc_loadMagazineTimer.sqf b/addons/mk6mortar/functions/fnc_loadMagazineTimer.sqf deleted file mode 100644 index cfc6adff08..0000000000 --- a/addons/mk6mortar/functions/fnc_loadMagazineTimer.sqf +++ /dev/null @@ -1,30 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Grey - * Loads Magazine into static weapon using a timer. - * - * Arguments: - * 0: Static - * 1: Unit - * 2: Time to load - * 3: Magazine Class (default: "") - * - * Return Value: - * None - * - * Example: - * [_target,_player,"ACE_1Rnd_82mm_Mo_HE"] call ace_mk6mortar_fnc_loadMagazineTimer - * - * Public: Yes - */ - -params ["_static","_unit","_timeToLoad",["_magazineClassOptional","",[""]]]; - -_static setVariable [QGVAR(inUse), true, true]; - -// Move player into animation if player is standing -if ((_unit call CBA_fnc_getUnitAnim) select 0 == "stand") then { - [_unit, "AmovPercMstpSrasWrflDnon_diary", 1] call EFUNC(common,doAnimation); -}; - -[_timeToLoad, [_static,_unit,_magazineClassOptional], {(_this select 0) call FUNC(loadMagazine); ((_this select 0) select 0) setVariable [QGVAR(inUse), nil, true]}, {((_this select 0) select 0) setVariable [QGVAR(inUse), nil, true]}, localize LSTRING(loadingMortar)] call EFUNC(common,progressBar); diff --git a/addons/mk6mortar/functions/fnc_mortarInit.sqf b/addons/mk6mortar/functions/fnc_mortarInit.sqf deleted file mode 100644 index 46c16738bf..0000000000 --- a/addons/mk6mortar/functions/fnc_mortarInit.sqf +++ /dev/null @@ -1,46 +0,0 @@ -#include "script_component.hpp" -/* - * Author: VKing - * Initializes mortar for use with ammunition handling magazines. - * - * Arguments: - * 0: Mortar - * - * Return Value: - * None - * - * Example: - * [mortar1] call ace_mk6mortar_fnc_mortarInit - * - * Public: No - */ - -params ["_mortar"]; - -if (_mortar getVariable [QGVAR(initialized),false] || _mortar getVariable [QGVAR(exclude),false]) exitWith {TRACE_1("Exit",_mortar)}; -if (!(_mortar turretLocal [0])) exitWith {TRACE_1("Exit - turret not local",_mortar)}; - -// Remove all magazines from turret -if (count magazines _mortar > 0) then { - { - _mortar removeMagazineTurret [_x,[0]]; - } forEach magazines _mortar; -}; - -// Replace current turret weapon with ammo handling weapon -private _currentWeapon = _mortar weaponsTurret [0] select 0; -private _newWeapon = ""; - -if (_currentWeapon == "mortar_82mm") then { - _newWeapon = "ace_mortar_82mm"; -} else { - _newWeapon = getText (configFile >> "CfgWeapons" >> _currentWeapon >> QGVAR(replaceWith)); -}; - -if (_newWeapon != "") then { - _mortar removeWeaponTurret [_currentWeapon,[0]]; - _mortar addWeaponTurret [_newWeapon,[0]]; -}; - -_mortar setVariable [QGVAR(initialized),true,true]; -TRACE_1("Init complete",_mortar); diff --git a/addons/mk6mortar/functions/fnc_unloadMagazine.sqf b/addons/mk6mortar/functions/fnc_unloadMagazine.sqf deleted file mode 100644 index 4da21b3e8f..0000000000 --- a/addons/mk6mortar/functions/fnc_unloadMagazine.sqf +++ /dev/null @@ -1,38 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Grey - * - * Unload current magazine from static weapon - * - * Arguments: - * 0: static - * 1: unit - * - * Return Value: - * None - * - * Example: - * [_target, _player] call ace_mk6mortar_fnc_unloadMagazine - * - * Public: Yes - */ - -params ["_static","_unit"]; - -//Get weapon & magazine information about static weapon -private _currentMagazine = (magazinesAllTurrets _static) select 1; -private _currentMagazineClass = _currentMagazine select 0; -private _ammoCount = _currentMagazine select 2; - -// Try to add the round to player inventory, otherwise place it on the ground near the player -if (_ammoCount > 0) then { - if (_unit canAdd _currentMagazineClass) then { - _unit addMagazineGlobal _currentMagazineClass; - } else { - _pos = _unit modelToWorldVisual [0.5,0.5,0]; // Front right of player - _unit = createVehicle ["WeaponHolder_Single_F",_pos,[],0,"NONE"]; - _unit addMagazineAmmoCargo [_currentMagazineClass, 1, _ammoCount]; - _unit setPosATL _pos; - }; - [QGVAR(removeMagazine), [_static, _currentMagazineClass]] call CBA_fnc_globalEvent; -}; diff --git a/addons/mk6mortar/functions/fnc_unloadMagazineTimer.sqf b/addons/mk6mortar/functions/fnc_unloadMagazineTimer.sqf deleted file mode 100644 index 4c152bc7d1..0000000000 --- a/addons/mk6mortar/functions/fnc_unloadMagazineTimer.sqf +++ /dev/null @@ -1,30 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Grey - * - * Unload current magazine from static weapon using a timer - * - * Arguments: - * 0: static - * 1: unit - * 2: time to unload - * - * Return Value: - * None - * - * Example: - * [_target, _player, 5] call ace_mk6mortar_fnc_unloadMagazineTimer - * - * Public: Yes - */ - -params ["_static","_unit","_timeToUnload"]; - -_static setVariable [QGVAR(inUse), true, true]; - -//Move player into animation if player is standing -if ((_unit call CBA_fnc_getUnitAnim) select 0 == "stand") then { - [_unit, "AmovPercMstpSrasWrflDnon_diary", 1] call EFUNC(common,doAnimation); -}; - -[_timeToUnload, [_static,_unit], {(_this select 0) call FUNC(unloadMagazine); ((_this select 0) select 0) setVariable [QGVAR(inUse), nil, true]}, {((_this select 0) select 0) setVariable [QGVAR(inUse), nil, true]}, localize LSTRING(unloadingMortar)] call EFUNC(common,progressBar); diff --git a/addons/mk6mortar/stringtable.xml b/addons/mk6mortar/stringtable.xml index a8f7740527..57ac571836 100644 --- a/addons/mk6mortar/stringtable.xml +++ b/addons/mk6mortar/stringtable.xml @@ -74,6 +74,8 @@ Mk6 迫撃砲 Mortier Mk6 Moździerz Mk6 + Миномет Mk6 + Morteiro Mk6 Mk6 Settings diff --git a/addons/movement/CfgMoves.hpp b/addons/movement/CfgMoves.hpp index c8273fcdb2..edf6bac4a3 100644 --- a/addons/movement/CfgMoves.hpp +++ b/addons/movement/CfgMoves.hpp @@ -57,13 +57,24 @@ class CfgMovesBasic { // jump animation - WEAPON LOWERED - RUNNING class RifleLowStandActionsNoAdjust; class RifleLowStandActionsRunF: RifleLowStandActionsNoAdjust { - getOver = "AovrPercMrunSrasWrflDf"; + getOver = "ACE_AovrPercMrunSlowWrflDf"; }; class RifleLowStandActionsRunFL: RifleLowStandActionsNoAdjust { - getOver = "AovrPercMrunSrasWrflDf"; + getOver = "ACE_AovrPercMrunSlowWrflDf"; }; class RifleLowStandActionsRunFR: RifleLowStandActionsNoAdjust { - getOver = "AovrPercMrunSrasWrflDf"; + getOver = "ACE_AovrPercMrunSlowWrflDf"; + }; + + // jump animation - WEAPON LOWERED - SPRINTING + class RifleStandLowEvasiveActionsF: RifleLowStandActionsNoAdjust { + getOver = "ACE_AovrPercMrunSlowWrflDf"; + }; + class RifleStandLowEvasiveActionsFR: RifleLowStandActionsNoAdjust { + getOver = "ACE_AovrPercMrunSlowWrflDf"; + }; + class RifleStandLowEvasiveActionsFL: RifleLowStandActionsNoAdjust { + getOver = "ACE_AovrPercMrunSlowWrflDf"; }; }; }; @@ -76,11 +87,178 @@ class CfgMovesMaleSdr: CfgMovesBasic { class AovrPercMrunSrasWrflDf: AovrPercMstpSrasWrflDf { forceAim = 0; }; + class ACE_AovrPercMrunSlowWrflDf: AovrPercMrunSrasWrflDf { // custom + actions = "RifleLowStandActionsRunF"; - // replace link of vault with jump animation + ConnectTo[] = { + "AidlPercMstpSlowWrflDnon_G0S",0.02, + "AmovPercMstpSlowWrflDnon",0.03, + "WeaponMagazineReloadStand",0.1, + //"AmovPercMstpSrasWrflDnon_AmovPercMstpSrasWlnrDnon",0.01, + "AmovPercMstpSlowWrflDnon_AmovPercMstpSrasWrflDnon",0.01, + //"AmovPercMstpSrasWrflDnon_AmovPercMstpSrasWpstDnon",0.02, + //"AmovPercMstpSrasWrflDnon_AwopPercMstpSoptWbinDnon",0.02, + //"AmovPercMstpSrasWrflDnon_AmovPercMstpSnonWnonDnon",0.02, + "AwopPercMstpSgthWrflDnon_Start2",0.1, + "AmovPercMstpSrasWrflDnon_AinvPknlMstpSlayWrflDnon",0.02, + //"AmovPercMstpSrasWrflDnon_AadjPercMstpSrasWrflDup",0.02, + //"AmovPercMstpSrasWrflDnon_AadjPercMstpSrasWrflDdown",0.02, + //"AmovPercMstpSrasWrflDnon_AadjPercMstpSrasWrflDleft",0.02, + //"AmovPercMstpSrasWrflDnon_AadjPercMstpSrasWrflDright",0.02, + "AmovPercMstpSrasWrflDnon_AmovPercMstpSrasWrflDnon_gear",0.02 + }; + InterpolateTo[] = { + "AmovPercMstpSlowWrflDnon_turnL",0.02, + "AmovPercMstpSlowWrflDnon_turnR",0.02, + "AmovPercMstpSlowWrflDnon_AmovPknlMstpSlowWrflDnon",0.01, + "AmovPercMstpSlowWrflDnon_AmovPpneMstpSrasWrflDnon",0.01, + "AmovPercMstpSlowWrflDnon_AcinPknlMwlkSlowWrflDb_1",0.01, + "Helper_SwitchToCarryRfl",0.2, + "AmovPercMstpSrasWrflDnon_AinvPercMstpSrasWrflDnon",0.02, + "AmovPercMstpSrasWrflDnon_AinvPercMstpSrasWrflDnon_Putdown",0.02, + "AmovPercMwlkSlowWrflDf",0.02, + "AmovPercMwlkSlowWrflDfl",0.02, + "AmovPercMwlkSlowWrflDl",0.02, + "AmovPercMwlkSlowWrflDbl",0.02, + "AmovPercMwlkSlowWrflDb",0.02, + "AmovPercMwlkSlowWrflDbr",0.02, + "AmovPercMwlkSlowWrflDr",0.02, + "AmovPercMwlkSlowWrflDfr",0.02, + "AmovPercMrunSlowWrflDf",0.02, + "AmovPercMrunSlowWrflDfl",0.02, + "AmovPercMrunSlowWrflDl",0.02, + "AmovPercMrunSlowWrflDbl",0.02, + "AmovPercMrunSlowWrflDb",0.02, + "AmovPercMrunSlowWrflDbr",0.02, + "AmovPercMrunSlowWrflDr",0.02, + "AmovPercMrunSlowWrflDfr",0.02, + //"AmovPercMrunSrasWrflDf_ldst",0.02, + //"AmovPercMrunSrasWrflDfl_ldst",0.02, + //"AmovPercMrunSrasWrflDl_ldst",0.02, + //"AmovPercMrunSrasWrflDbl_ldst",0.02, + //"AmovPercMrunSrasWrflDb_ldst",0.02, + //"AmovPercMrunSrasWrflDbr_ldst",0.02, + //"AmovPercMrunSrasWrflDr_ldst",0.02, + //"AmovPercMrunSrasWrflDfr_ldst",0.02, + "AmovPercMstpSlowWrflDnon_AmovPknlMstpSlowWrflDnon",0.02, + "AmovPercMevaSlowWrflDf",0.02, + "AmovPercMevaSlowWrflDfl",0.02, + "AmovPercMevaSlowWrflDfr",0.02, + "AmovPercMstpSlowWrflDnon_SaluteIn",0.03, + "Unconscious",0.02, + "AidlPercMstpSlowWrflDnon_AI",0.02, + "AidlPercMstpSlowWrflDnon_AI",0.02, + "AovrPercMstpSlowWrflDf",1.01, + "AmovPercMtacSlowWrflDfl",0.2, + "AmovPercMtacSlowWrflDl",0.2, + "AmovPercMtacSlowWrflDbl",0.2, + "AmovPercMtacSlowWrflDb",0.2, + "AmovPercMtacSlowWrflDbr",0.2, + "AmovPercMtacSlowWrflDr",0.2, + "AmovPercMtacSlowWrflDfr",0.22, + "AmovPercMtacSlowWrflDf",0.02, + "HaloFreeFall_non",10.2, + "AmovPercMrunSlowWrflDf",0.02, + "AmovPercMrunSlowWrflDfl",0.02, + "AmovPercMrunSlowWrflDl",0.02, + "AmovPercMrunSlowWrflDb",0.02, + "AmovPercMrunSlowWrflDbr",0.02, + "AmovPercMrunSlowWrflDr",0.02, + "AmovPercMrunSlowWrflDbl",0.02, + "AmovPercMrunSlowWrflDfr",0.02, + "AmovPercMstpSrasWrflDnon_falling",0.02, + "AsdvPercMstpSnonWrflDnon",2.02, + "AdvePercMstpSnonWrflDnon",2.02, + "AbdvPercMstpSnonWrflDnon",2.02, + "AinvPercMstpSrasWrflDnon",0.05, + "AmovPknlMstpSlowWrflDnon_AmovPercMstpSlowWrflDnon",0.02, + //"AmovPpneMstpSrasWrflDnon_AmovPercMstpSrasWrflDnon",0.02, + //"AmovPercMstpSlowWrflDnon_AmovPercMstpSrasWrflDnon",0.02, + "AmovPercMstpSlowWrflDnon_AmovPsitMstpSlowWrflDnon",0.02, + "AfalPercMstpSrasWrflDnon",0.025, + //"AmovPercMevaSrasWrflDl",0.025, + //"AmovPercMevaSrasWrflDr",0.025, + "Acts_PercMstpSlowWrflDnon_handup2",1, + "Acts_WalkingChecking",1, + "Acts_PercMstpSlowWrflDnon_handup1",1, + "Acts_PercMstpSlowWrflDnon_handup2b",1, + "Acts_PercMstpSlowWrflDnon_handup2c",1, + "Acts_PercMstpSlowWrflDnon_handup1b",1, + "Acts_PercMstpSlowWrflDnon_handup1c",1, + "HubSpectator_stand",1, + "HubSpectator_walk",1, + "HubStanding_idle1",1, + "HubStanding_idle2",1, + "HubStanding_idle3",1, + "Campaign_Base",0.5, + "CutSceneAnimationBase",0.5, + "AmovPercMlmpSlowWrflDf",0.05, + "AmovPercMlmpSlowWrflDfl",0.05, + "AmovPercMlmpSlowWrflDl",0.05, + "AmovPercMlmpSlowWrflDbl",0.05, + "AmovPercMlmpSlowWrflDb",0.05, + "AmovPercMlmpSlowWrflDbr",0.05, + "AmovPercMlmpSlowWrflDr",0.05, + "AmovPercMlmpSlowWrflDfr",0.05, + "acts_millerDisarming_runToDesk",0.05, + "CutSceneAnimationSmk",0.1, + "UnconsciousFaceDown",0.25, + "UnconsciousMedicFromRifle",0.2 + }; + }; + + // rifle raised, replace link of vault with jump animation class AmovPercMstpSrasWrflDnon; class AmovPercMrunSrasWrflDf: AmovPercMstpSrasWrflDnon { - InterpolateTo[] = {"AovrPercMrunSrasWrflDf",0.22,"AmovPercMrunSlowWrflDf",0.025,"AmovPercMwlkSrasWrflDf",0.025,"AmovPknlMrunSrasWrflDf",0.03,"AmovPercMrunSlowWrflDf_AmovPpneMstpSrasWrflDnon",0.02,"AmovPercMevaSrasWrflDf",0.025,"Unconscious",0.01,"AmovPercMtacSrasWrflDf",0.02,"AmovPercMrunSrasWrflDfl",0.02,"AmovPercMrunSrasWrflDfl_ldst",0.02,"AmovPercMrunSrasWrflDfr",0.02,"AmovPercMrunSrasWrflDfr_ldst",0.02,"AmovPercMstpSrasWrflDnon",0.02,"AmovPercMrunSrasWrflDl",0.02,"AmovPercMrunSrasWrflDbl",0.02,"AmovPercMrunSrasWrflDb",0.02,"AmovPercMrunSrasWrflDbr",0.02,"AmovPercMrunSrasWrflDr",0.02,"AmovPknlMstpSlowWrflDnon_relax",0.1,"AmovPercMrunSrasWrflDf_ldst",0.02,"AmovPercMrunSrasWrflDf",0.02}; + InterpolateTo[] = { + "AovrPercMrunSrasWrflDf",0.22, + "AmovPercMrunSlowWrflDf",0.025, + "AmovPercMwlkSrasWrflDf",0.025, + "AmovPknlMrunSrasWrflDf",0.03, + "AmovPercMrunSlowWrflDf_AmovPpneMstpSrasWrflDnon",0.02, + "AmovPercMevaSrasWrflDf",0.025, + "Unconscious",0.01, + "AmovPercMtacSrasWrflDf",0.02, + "AmovPercMrunSrasWrflDfl",0.02, + "AmovPercMrunSrasWrflDfl_ldst",0.02, + "AmovPercMrunSrasWrflDfr",0.02, + "AmovPercMrunSrasWrflDfr_ldst",0.02, + "AmovPercMstpSrasWrflDnon",0.02, + "AmovPercMrunSrasWrflDl",0.02, + "AmovPercMrunSrasWrflDbl",0.02, + "AmovPercMrunSrasWrflDb",0.02, + "AmovPercMrunSrasWrflDbr",0.02, + "AmovPercMrunSrasWrflDr",0.02, + "AmovPknlMstpSlowWrflDnon_relax",0.1, + "AmovPercMrunSrasWrflDf_ldst",0.02, + "AmovPercMrunSrasWrflDf",0.02 + }; + }; + + // rifle lowered, add link to jump animation + class AmovPercMstpSlowWrflDnon; + class AmovPercMrunSlowWrflDf: AmovPercMstpSlowWrflDnon { + InterpolateTo[] = { + "ACE_AovrPercMrunSlowWrflDf",0.22, + "AmovPercMstpSlowWrflDnon",0.02, + "AmovPercMwlkSlowWrflDf_ver2",0.025, + "AmovPercMwlkSlowWrflDf",0.5, + "AidlPercMrunSrasWrflDf",0.01, + "AmovPercMrunSlowWrflDfl",0.025, + "AmovPercMrunSlowWrflDfr",0.025, + "AmovPercMrunSrasWrflDf",0.025, + "AmovPknlMrunSlowWrflDf",0.03, + "AmovPercMrunSlowWrflDf_AmovPpneMstpSrasWrflDnon",0.02, + "AmovPercMevaSrasWrflDf",0.025, + "AmovPercMevaSlowWrflDf",0.025, + "Unconscious",0.02, + "AmovPercMrunSlowWrflDf_AmovPercMstpSrasWrflDnon_gthStart",0.1, + "AmovPknlMstpSlowWrflDnon_relax",0.1, + "AmovPercMtacSlowWrflDf_ver2",0.2, + "AmovPercMtacSlowWrflDf",0.5, + "AmovPercMwlkSrasWrflDf",0.02, + "AmovPercMtacSrasWrflDf",0.02 + }; }; // enable optics in prone down stance diff --git a/addons/movement/functions/fnc_inventoryDisplayLoad.sqf b/addons/movement/functions/fnc_inventoryDisplayLoad.sqf index d107bd70b1..cdbc85a895 100644 --- a/addons/movement/functions/fnc_inventoryDisplayLoad.sqf +++ b/addons/movement/functions/fnc_inventoryDisplayLoad.sqf @@ -17,11 +17,15 @@ params ["_display"]; +// 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 ["%1 - %2 %3 (%4)", + _control ctrlSetText format [_format, [ACE_player, false, true] call EFUNC(common,getName), localize ELSTRING(common,Weight), [ACE_player] call EFUNC(common,getWeight), diff --git a/addons/movement/stringtable.xml b/addons/movement/stringtable.xml index 45a3bf65c3..38790f655b 100644 --- a/addons/movement/stringtable.xml +++ b/addons/movement/stringtable.xml @@ -43,7 +43,7 @@ Здесь невозможно взобраться Itt nem tudsz mászni Non puoi arrampicarti qui - Não se pode subir aqui + Não pode subir aqui ここは登れません 这里无法攀爬 這裡無法攀爬 diff --git a/addons/nametags/CfgFactionClasses.hpp b/addons/nametags/CfgFactionClasses.hpp new file mode 100644 index 0000000000..0e41b5823f --- /dev/null +++ b/addons/nametags/CfgFactionClasses.hpp @@ -0,0 +1,79 @@ +class CfgFactionClasses { + class OPF_F { + GVAR(rankIcons)[] = { + QPATHTOF(UI\icons_russia\private_gs.paa), + QPATHTOF(UI\icons_russia\corporal_gs.paa), + QPATHTOF(UI\icons_russia\sergeant_gs.paa), + QPATHTOF(UI\icons_russia\lieutenant_gs.paa), + QPATHTOF(UI\icons_russia\captain_gs.paa), + QPATHTOF(UI\icons_russia\major_gs.paa), + QPATHTOF(UI\icons_russia\colonel_gs.paa) + }; + }; + class OPF_G_F { + GVAR(rankIcons)[] = { + QPATHTOF(UI\icons_spain\private_gs.paa), + QPATHTOF(UI\icons_spain\corporal_gs.paa), + QPATHTOF(UI\icons_spain\sergeant_gs.paa), + QPATHTOF(UI\icons_spain\lieutenant_gs.paa), + QPATHTOF(UI\icons_spain\captain_gs.paa), + QPATHTOF(UI\icons_spain\major_gs.paa), + QPATHTOF(UI\icons_spain\colonel_gs.paa) + }; + }; + class OPF_T_F { + GVAR(rankIcons)[] = { + QPATHTOF(UI\icons_russia\private_gs.paa), + QPATHTOF(UI\icons_russia\corporal_gs.paa), + QPATHTOF(UI\icons_russia\sergeant_gs.paa), + QPATHTOF(UI\icons_russia\lieutenant_gs.paa), + QPATHTOF(UI\icons_russia\captain_gs.paa), + QPATHTOF(UI\icons_russia\major_gs.paa), + QPATHTOF(UI\icons_russia\colonel_gs.paa) + }; + }; + class OPF_V_F { + GVAR(rankIcons)[] = { + QPATHTOF(UI\icons_russia\private_gs.paa), + QPATHTOF(UI\icons_russia\corporal_gs.paa), + QPATHTOF(UI\icons_russia\sergeant_gs.paa), + QPATHTOF(UI\icons_russia\lieutenant_gs.paa), + QPATHTOF(UI\icons_russia\captain_gs.paa), + QPATHTOF(UI\icons_russia\major_gs.paa), + QPATHTOF(UI\icons_russia\colonel_gs.paa) + }; + }; + class IND_C_F { + GVAR(rankIcons)[] = { + QPATHTOF(UI\icons_russia\private_gs.paa), + QPATHTOF(UI\icons_russia\corporal_gs.paa), + QPATHTOF(UI\icons_russia\sergeant_gs.paa), + QPATHTOF(UI\icons_russia\lieutenant_gs.paa), + QPATHTOF(UI\icons_russia\captain_gs.paa), + QPATHTOF(UI\icons_russia\major_gs.paa), + QPATHTOF(UI\icons_russia\colonel_gs.paa) + }; + }; + class IND_F { + GVAR(rankIcons)[] = { + QPATHTOF(UI\icons_germany\private_gs.paa), + QPATHTOF(UI\icons_germany\corporal_gs.paa), + QPATHTOF(UI\icons_germany\sergeant_gs.paa), + QPATHTOF(UI\icons_germany\lieutenant_gs.paa), + QPATHTOF(UI\icons_germany\captain_gs.paa), + QPATHTOF(UI\icons_germany\major_gs.paa), + QPATHTOF(UI\icons_germany\colonel_gs.paa) + }; + }; + class IND_G_F { + GVAR(rankIcons)[] = { + QPATHTOF(UI\icons_spain\private_gs.paa), + QPATHTOF(UI\icons_spain\corporal_gs.paa), + QPATHTOF(UI\icons_spain\sergeant_gs.paa), + QPATHTOF(UI\icons_spain\lieutenant_gs.paa), + QPATHTOF(UI\icons_spain\captain_gs.paa), + QPATHTOF(UI\icons_spain\major_gs.paa), + QPATHTOF(UI\icons_spain\colonel_gs.paa) + }; + }; +}; diff --git a/addons/nametags/UI/icons_france/captain_gs.paa b/addons/nametags/UI/icons_france/captain_gs.paa new file mode 100644 index 0000000000..b9cceddc05 Binary files /dev/null and b/addons/nametags/UI/icons_france/captain_gs.paa differ diff --git a/addons/nametags/UI/icons_france/colonel_gs.paa b/addons/nametags/UI/icons_france/colonel_gs.paa new file mode 100644 index 0000000000..b0119b21d5 Binary files /dev/null and b/addons/nametags/UI/icons_france/colonel_gs.paa differ diff --git a/addons/nametags/UI/icons_france/corporal_gs.paa b/addons/nametags/UI/icons_france/corporal_gs.paa new file mode 100644 index 0000000000..b6f5b6a2ca Binary files /dev/null and b/addons/nametags/UI/icons_france/corporal_gs.paa differ diff --git a/addons/nametags/UI/icons_france/lieutenant_gs.paa b/addons/nametags/UI/icons_france/lieutenant_gs.paa new file mode 100644 index 0000000000..7792c8e87a Binary files /dev/null and b/addons/nametags/UI/icons_france/lieutenant_gs.paa differ diff --git a/addons/nametags/UI/icons_france/major_gs.paa b/addons/nametags/UI/icons_france/major_gs.paa new file mode 100644 index 0000000000..b7b31a10f4 Binary files /dev/null and b/addons/nametags/UI/icons_france/major_gs.paa differ diff --git a/addons/nametags/UI/icons_france/private_gs.paa b/addons/nametags/UI/icons_france/private_gs.paa new file mode 100644 index 0000000000..abb2251112 Binary files /dev/null and b/addons/nametags/UI/icons_france/private_gs.paa differ diff --git a/addons/nametags/UI/icons_france/sergeant_gs.paa b/addons/nametags/UI/icons_france/sergeant_gs.paa new file mode 100644 index 0000000000..afa48f04c8 Binary files /dev/null and b/addons/nametags/UI/icons_france/sergeant_gs.paa differ diff --git a/addons/nametags/UI/icons_germany/captain_gs.paa b/addons/nametags/UI/icons_germany/captain_gs.paa new file mode 100644 index 0000000000..cf99a2cb40 Binary files /dev/null and b/addons/nametags/UI/icons_germany/captain_gs.paa differ diff --git a/addons/nametags/UI/icons_germany/colonel_gs.paa b/addons/nametags/UI/icons_germany/colonel_gs.paa new file mode 100644 index 0000000000..d46b75527c Binary files /dev/null and b/addons/nametags/UI/icons_germany/colonel_gs.paa differ diff --git a/addons/nametags/UI/icons_germany/corporal_gs.paa b/addons/nametags/UI/icons_germany/corporal_gs.paa new file mode 100644 index 0000000000..a02673671d Binary files /dev/null and b/addons/nametags/UI/icons_germany/corporal_gs.paa differ diff --git a/addons/nametags/UI/icons_germany/lieutenant_gs.paa b/addons/nametags/UI/icons_germany/lieutenant_gs.paa new file mode 100644 index 0000000000..9423487ede Binary files /dev/null and b/addons/nametags/UI/icons_germany/lieutenant_gs.paa differ diff --git a/addons/nametags/UI/icons_germany/major_gs.paa b/addons/nametags/UI/icons_germany/major_gs.paa new file mode 100644 index 0000000000..f6ef27fad2 Binary files /dev/null and b/addons/nametags/UI/icons_germany/major_gs.paa differ diff --git a/addons/nametags/UI/icons_germany/private_gs.paa b/addons/nametags/UI/icons_germany/private_gs.paa new file mode 100644 index 0000000000..abb2251112 Binary files /dev/null and b/addons/nametags/UI/icons_germany/private_gs.paa differ diff --git a/addons/nametags/UI/icons_germany/sergeant_gs.paa b/addons/nametags/UI/icons_germany/sergeant_gs.paa new file mode 100644 index 0000000000..b3b855ef56 Binary files /dev/null and b/addons/nametags/UI/icons_germany/sergeant_gs.paa differ diff --git a/addons/nametags/UI/icons_spain/captain_gs.paa b/addons/nametags/UI/icons_spain/captain_gs.paa new file mode 100644 index 0000000000..1d271583be Binary files /dev/null and b/addons/nametags/UI/icons_spain/captain_gs.paa differ diff --git a/addons/nametags/UI/icons_spain/colonel_gs.paa b/addons/nametags/UI/icons_spain/colonel_gs.paa new file mode 100644 index 0000000000..8f1e308d9d Binary files /dev/null and b/addons/nametags/UI/icons_spain/colonel_gs.paa differ diff --git a/addons/nametags/UI/icons_spain/corporal_gs.paa b/addons/nametags/UI/icons_spain/corporal_gs.paa new file mode 100644 index 0000000000..af3a9a7cbc Binary files /dev/null and b/addons/nametags/UI/icons_spain/corporal_gs.paa differ diff --git a/addons/nametags/UI/icons_spain/lieutenant_gs.paa b/addons/nametags/UI/icons_spain/lieutenant_gs.paa new file mode 100644 index 0000000000..5ce43d7437 Binary files /dev/null and b/addons/nametags/UI/icons_spain/lieutenant_gs.paa differ diff --git a/addons/nametags/UI/icons_spain/major_gs.paa b/addons/nametags/UI/icons_spain/major_gs.paa new file mode 100644 index 0000000000..a3844c8ce2 Binary files /dev/null and b/addons/nametags/UI/icons_spain/major_gs.paa differ diff --git a/addons/nametags/UI/icons_spain/private_gs.paa b/addons/nametags/UI/icons_spain/private_gs.paa new file mode 100644 index 0000000000..b486dd488c Binary files /dev/null and b/addons/nametags/UI/icons_spain/private_gs.paa differ diff --git a/addons/nametags/UI/icons_spain/sergeant_gs.paa b/addons/nametags/UI/icons_spain/sergeant_gs.paa new file mode 100644 index 0000000000..aa76186ddb Binary files /dev/null and b/addons/nametags/UI/icons_spain/sergeant_gs.paa differ diff --git a/addons/nametags/UI/icons_uk/captain_gs.paa b/addons/nametags/UI/icons_uk/captain_gs.paa new file mode 100644 index 0000000000..aeb89e3043 Binary files /dev/null and b/addons/nametags/UI/icons_uk/captain_gs.paa differ diff --git a/addons/nametags/UI/icons_uk/colonel_gs.paa b/addons/nametags/UI/icons_uk/colonel_gs.paa new file mode 100644 index 0000000000..b0a6e4851f Binary files /dev/null and b/addons/nametags/UI/icons_uk/colonel_gs.paa differ diff --git a/addons/nametags/UI/icons_uk/corporal_gs.paa b/addons/nametags/UI/icons_uk/corporal_gs.paa new file mode 100644 index 0000000000..2f664f8b3a Binary files /dev/null and b/addons/nametags/UI/icons_uk/corporal_gs.paa differ diff --git a/addons/nametags/UI/icons_uk/lieutenant_gs.paa b/addons/nametags/UI/icons_uk/lieutenant_gs.paa new file mode 100644 index 0000000000..8b8f707f6e Binary files /dev/null and b/addons/nametags/UI/icons_uk/lieutenant_gs.paa differ diff --git a/addons/nametags/UI/icons_uk/major_gs.paa b/addons/nametags/UI/icons_uk/major_gs.paa new file mode 100644 index 0000000000..562ce1599c Binary files /dev/null and b/addons/nametags/UI/icons_uk/major_gs.paa differ diff --git a/addons/nametags/UI/icons_uk/private_gs.paa b/addons/nametags/UI/icons_uk/private_gs.paa new file mode 100644 index 0000000000..abb2251112 Binary files /dev/null and b/addons/nametags/UI/icons_uk/private_gs.paa differ diff --git a/addons/nametags/UI/icons_uk/sergeant_gs.paa b/addons/nametags/UI/icons_uk/sergeant_gs.paa new file mode 100644 index 0000000000..e1041d08a9 Binary files /dev/null and b/addons/nametags/UI/icons_uk/sergeant_gs.paa differ diff --git a/addons/nametags/XEH_postInit.sqf b/addons/nametags/XEH_postInit.sqf index 2df7565cd6..e73794600d 100644 --- a/addons/nametags/XEH_postInit.sqf +++ b/addons/nametags/XEH_postInit.sqf @@ -45,3 +45,15 @@ GVAR(showNamesTime) = -10; // civilians don't use military ranks ["CIV_F", ["","","","","","",""]] call FUNC(setFactionRankIcons); + +// Change ranks based on faction for all factions that have an entry in CfgFactionClasses +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 + private _icons = getArray (_x >> QGVAR(rankIcons)); + [_faction, _icons] call FUNC(setFactionRankIcons); + }; + } forEach ("true" configClasses (configFile >> "CfgFactionClasses")); +}; diff --git a/addons/nametags/config.cpp b/addons/nametags/config.cpp index 0f491efce1..2db10c7eeb 100644 --- a/addons/nametags/config.cpp +++ b/addons/nametags/config.cpp @@ -16,6 +16,7 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "ACE_Settings.hpp" +#include "CfgFactionClasses.hpp" #include "CfgVehicles.hpp" #include diff --git a/addons/nametags/functions/fnc_setFactionRankIcons.sqf b/addons/nametags/functions/fnc_setFactionRankIcons.sqf index fa7975d5e5..e60c295c7d 100644 --- a/addons/nametags/functions/fnc_setFactionRankIcons.sqf +++ b/addons/nametags/functions/fnc_setFactionRankIcons.sqf @@ -29,6 +29,7 @@ if (isNil QGVAR(factionRanks)) then { }; params [["_faction", "", [""]], ["_icons", [], [[]], [7]]]; +TRACE_2("setFactionRankIcons",_faction,_icons); if !(_faction != "" && {_icons isEqualTypeAll ""}) exitWith {false}; diff --git a/addons/nametags/stringtable.xml b/addons/nametags/stringtable.xml index dd75dafe80..958062a81a 100644 --- a/addons/nametags/stringtable.xml +++ b/addons/nametags/stringtable.xml @@ -538,14 +538,19 @@ Sfocatura nei bordi dello schermo 在荧幕边框旁淡出 在螢幕邊框旁淡出 + Затухание на границе экрана + Ocultar na borda da tela Player tags transparency + Spielernamen Transparenz プレイヤー名札の透明度 玩家名字标签透明度 玩家名稱透明度 Trasparenza Etichette Nome Przezroczystość etykiet gracza + Прозрачность меток игроков + Transparência da etiqueta de nome diff --git a/addons/nightvision/stringtable.xml b/addons/nightvision/stringtable.xml index 3c5e9115f0..e374f3793a 100644 --- a/addons/nightvision/stringtable.xml +++ b/addons/nightvision/stringtable.xml @@ -10,6 +10,8 @@ ACE夜视镜 ACE Vision Nocturne ACE Noktowizja + ACE ПНВ + ACE Visão Noturna NV Goggles (Gen1) @@ -190,7 +192,7 @@ Nightvision Nachtsicht - Ночное виденье + Ночное видение Visão Noturna Noční vidění Noktowizja @@ -205,7 +207,7 @@ Settings for night vision. Einstellungen für Nachtsichtgeräte. - Настройки ночного виденья + Настройки приборов ночного видения Ajustes para visão noturna. Nastavení nočního vidění Ustawienia noktowizorów @@ -235,7 +237,7 @@ Blocks the usage of night vision goggles whilst aiming down the sight. Blockiert die Nachtsichtbrillen beim Verwenden des Visiers. - Блокирует использование головного ПНВ при прицеливании через прицел. + Блокирует использование головного ПНВ при прицеливании Bloqueia o uso de visão noturna ao utilizar a mira. Zabraňuje používání nokovizoru v režimu zaměřovače. Uniemożliwia korzystanie z gogli noktowizyjnych przy celowaniu. @@ -256,6 +258,8 @@ 夜视镜雾气程度 Épaisseur du brouillard (JVN) Skala Mgły NVG + Степень размытия ПНВ + Escala de Névoa na NVG Fog is used to limit visibility. @@ -266,6 +270,8 @@ 透过雾气来缩减夜视镜的可视距离。 Le brouillard est utilisé pour limiter la visibilité Mgła jest wykorzystywana do ograniczenia widoczności. + Туман используется для ограничения видимости + Névoa é usada para limitar visibilidade. NVG Effect Scale @@ -276,6 +282,8 @@ 夜视镜效果程度 Intensité des effets Skala Efektów NVG + Степень эффектов ПНВ + Intensidade de efeito da Visão Noturna Blur and brightness effects [Setting to 0 will disable ALL nightvision effects] @@ -286,6 +294,8 @@ 调整模糊与亮度的效果。[设值为0会关闭所有夜视镜的特殊效果] Effets de flou et de luminosité [Règler cette option sur 0 désactivera TOUS les effets de vision nocturne] Efekty rozmazania i jasności [Ustawienie na 0 wyłączy WSZYSTKIE efekty noktowizji] + Эффекты размытия и яркости [Установка на 0 отключит ВСЕ эффекты ПНВ] + Efeitos de borrão e brilho [Definir 0 desativa TODOS os efeitos da Visão Noturna] Aim Down Sights Blur @@ -296,6 +306,8 @@ Flou de visée Blur durante la mira Rozmazanie podczas celowania z narządów celowniczych + Размытие при опущеном прицеле + Borrão ao mirar NVG Noise Scale @@ -306,6 +318,8 @@ Intensité du bruit (JVN) Fattore di Disturbo del NVG Skala Szumu NVG + Степень шума ПНВ + Intensidade de Ruído/Efeito Granulado Image noise intensity when wearing NVGs @@ -316,24 +330,32 @@ Intensité du bruit de l'image lorsque vous portez des JVN Intensità del disturbo dell'immagine quando i NVG sono equipaggiati Intensywność efektu szumu podczas noszenia gogli noktowizyjnych + Интенсивность шума при использовании ПНВ + Intensidade de Ruído de Imagem ao utilizar Visão Noturna Shutter Effects + Rolling-Shutter-Effekt シャッター効果 快门效果 快門效果 Effets d'obturateur Effetti lampeggianti Efekt Shutter + Эффекты затвора + Efeito de Obturador Rolling shutter effect from muzzle flashes + Rolling-Shutter-Effekt bei Müdungsfeuer 発射炎が作るローリング シャッター効果です 枪械开火时产生瞬间快门效果 槍開火時瞬間產生快門效果 Effets d'obturateur à rideau dû aux flashs du canon Effetto lampeggiante dato dal lampo dello sparo Efekt rolling shutter z błysków wylotowych + Эффект затвора при вспышках выстрелов + Efeito de rolamento de Obturador de flashes de focinho diff --git a/addons/nlaw/stringtable.xml b/addons/nlaw/stringtable.xml index c986467887..b639a1bd16 100644 --- a/addons/nlaw/stringtable.xml +++ b/addons/nlaw/stringtable.xml @@ -10,6 +10,8 @@ 次世代輕型反坦克導彈發射器追蹤目標 (按住) Śledzenie Celu NLAW (Przytrzymaj) NLAW 목표 추적 (누름유지) + NLAW наведение на цель (Удерживать) + NLAW Rastrear Alvo (Segurar) Direct Attack @@ -20,6 +22,8 @@ 直射模式 Bezpośredni atak 직접 사격 + Прямая атака + Ataque Direto Overfly Top Attack @@ -30,6 +34,8 @@ 攻頂模式 Atak z góry 탑어택 + Атака сверху + Ataque por cima diff --git a/addons/noradio/stringtable.xml b/addons/noradio/stringtable.xml index d8aa43d4e2..21901168e6 100644 --- a/addons/noradio/stringtable.xml +++ b/addons/noradio/stringtable.xml @@ -9,6 +9,8 @@ 玩家静音 プレイヤーをミュート Wycisz Gracza + Заглушить игрока + Silenciar Jogador Mutes the controlled player avatar. @@ -18,6 +20,8 @@ 静音玩家所控制的角色。 プレイヤーに操作されているこのキャラをミュートします。 Wycisza awatar kontrolowany przez gracza + Заглушить контролируемого игрока + Silencia o avatar do Jogador controlado diff --git a/addons/optionsmenu/config.cpp b/addons/optionsmenu/config.cpp index b17fe12cc3..5661753579 100644 --- a/addons/optionsmenu/config.cpp +++ b/addons/optionsmenu/config.cpp @@ -30,7 +30,10 @@ class CfgAddons { #include "gui\pauseMenu.hpp" class ACE_Extensions { - extensions[] += {"ace_clipboard"}; + class ace_clipboard { + windows = 1; + client = 1; + }; }; class CfgCommands { diff --git a/addons/optionsmenu/functions/fnc_debugDumpToClipboard.sqf b/addons/optionsmenu/functions/fnc_debugDumpToClipboard.sqf index 3b662eb121..6ed460d2f9 100644 --- a/addons/optionsmenu/functions/fnc_debugDumpToClipboard.sqf +++ b/addons/optionsmenu/functions/fnc_debugDumpToClipboard.sqf @@ -15,7 +15,7 @@ * Public: No */ -#define MIN_ARRAY_SIZE 50 +#define MIN_ARRAY_SIZE 100 private _outputText = { diag_log text (_this select 0); @@ -24,8 +24,7 @@ private _outputText = { }; private _text = format ["~~~~~~~~~ACE Debug~~~~~~~~~ -time = %1 - +%1 ------Performance------ diag_fps = %2 count cba_common_waitAndExecArray = %3 @@ -34,11 +33,11 @@ count cba_common_perFrameHandlerArray = %5 (max %6) count diag_activeSQFScripts = %7 count diag_activeSQSScripts = %8 count diag_activeMissionFSMs = %9", -time, +format ["[Time: %1] [CBA_missionTime: %2] [tickTime: %3]", time toFixed 1, CBA_missionTime toFixed 1, diag_tickTime toFixed 1], diag_fps, count cba_common_waitAndExecArray, count cba_common_waitUntilAndExecArray, -{!isNil "_x"} count cba_common_perFrameHandlerArray, count cba_common_perFrameHandlerArray, +count cba_common_perFrameHandlerArray, count cba_common_PFHhandles, count diag_activeSQFScripts, count diag_activeSQSScripts, count diag_activeMissionFSMs]; @@ -54,16 +53,20 @@ if (isNull ace_player) then {"null"} else {animationState ace_player}]; [_text] call _outputText; -_text = format [" -------ACE's CBA Settings------"]; -[_text] call _outputText; - private _aceSettings = cba_settings_allSettings select {((_x select [0,4]) == "ace_") || {(_x select [0,5]) == "acex_"}}; _aceSettings sort true; +_text = format [" +------ACE's CBA Settings [%1 Total] [Only Non-Defaults]------", count _aceSettings]; +[_text] call _outputText; + { - _var = missionNamespace getVariable [_x, "ERROR: Not Defined"]; - _text = format ["%1 - %2", _x, _var]; - [_text] call _outputText; + private _currentValue = missionNamespace getVariable [_x, "$"]; + private _defaultValue = (cba_settings_default getVariable [_x, []]) param [0, "#"]; + if (_currentValue isEqualTo _defaultValue) then { + // [format ["%1 - %2 - DEFAULT", _x, _currentValue]] call _outputText; + } else { + [format ["%1 - %2", _x, _currentValue]] call _outputText; + }; } forEach _aceSettings; diff --git a/addons/overheating/stringtable.xml b/addons/overheating/stringtable.xml index 9ea7e36a06..c3a557951f 100644 --- a/addons/overheating/stringtable.xml +++ b/addons/overheating/stringtable.xml @@ -9,6 +9,8 @@ 过热 過熱 Przegrzewanie + Перегрев + Super Aquecimento Display text on jam diff --git a/addons/overpressure/stringtable.xml b/addons/overpressure/stringtable.xml index 6dca54adcb..06d83cbcd9 100644 --- a/addons/overpressure/stringtable.xml +++ b/addons/overpressure/stringtable.xml @@ -11,6 +11,8 @@ Coefficente Distanza Sovrapressione 高压影响距离系数 高壓影響距離係數 + Коэффициент избыточного давления + Coeficiente de Distância de Sobrepressão Scales the overpressure effect [Default: 1] @@ -22,22 +24,30 @@ Scala l'effetto di sovrapressione [Predefinito: 1] 高压影响的范围 [预设: 1] 高壓影響的範圍 [預設: 1] + Степень зависимости избыточного давления от расстояния [По умолчанию: 1] + Escala o efeito de sobrepressão [Padrão: 1] Backblast range + Rückstoßbereich 後方噴射の範囲 向后喷射的范围 後方尾焰的範圍 Raggio della fiammata [lanciarazzi] Zasięg backblast'u + Дальность реактивной струи + Alcance do Sopro de Disparo Backblast angle + Rückstoßwinkel 後方噴射の角度 向后喷射的角度 後方尾焰的角度 Angolo della fiammata [lanciarazzi] Kąt backblast'u + Угол реактивной струи + Ângulo do Sopro de Disparo diff --git a/addons/parachute/stringtable.xml b/addons/parachute/stringtable.xml index facea0a4ed..7a48392da7 100644 --- a/addons/parachute/stringtable.xml +++ b/addons/parachute/stringtable.xml @@ -105,6 +105,8 @@ 隱藏自由落體高度計 隐藏自由落体高度计 Schowaj wysokościomierz podczas swobodnego opadania + Убрать высотомер при падении + Esconder Altímetro de queda livre Hides the altitude and speed shown while free falling or parachuting. @@ -114,6 +116,8 @@ 在自由落體時或開傘下隱藏自由落體高度計 在自由落体时或开伞下隐藏自由落体高度计。 Chowa wysokość i prędkość pokazywaną podczas swobodnego opadania lub spadania ze spadochronem. + Скрывает показания высоты и скорости при свободном падении или прыжках с парашютом. + Esconde a altitude e velocidade enquanto estiver em queda livre ou saltando de paraquedas. diff --git a/addons/pylons/stringtable.xml b/addons/pylons/stringtable.xml index a1949e816c..bb52832708 100644 --- a/addons/pylons/stringtable.xml +++ b/addons/pylons/stringtable.xml @@ -11,6 +11,8 @@ AUSRÜSTUNG DES FLUGGERÄTS ÉQUIPEMENTS DE L'AÉRONEF WYPOSAŻENIE POJAZDU POWIETRZNEGO + СНАРЯЖЕНИЕ САМОЛЕТА + LOADOUT DA AERONAVE Loadouts for %1 @@ -22,6 +24,8 @@ Ausrüstung für %1 Équipements pour %1 Wyposażenia dla %1 + Оснащение %1 + Loadouts para %1 Configure Pylons @@ -33,6 +37,8 @@ Konfiguriere Außenlaststationen Configurer les pylônes Konfiguruj Pylony + Настройка Пилонов + Configurar Pylons ACE Pylons @@ -44,6 +50,8 @@ ACE Außenlaststationen ACE Pylônes Pylony ACE + ACE Пилоны + ACE Pylons <empty> @@ -55,6 +63,8 @@ <leer> <vide> <puste> + <пусто> + <vazio> Pylons that are colored red will have to be manually rearmed. @@ -66,6 +76,8 @@ Außenlaststationen, die rot markiert sind, müssen manuell aufmunitioniert werden. Les pylônes colorés en rouge devront être réarmés manuellement. Pylony, które są w kolorze czerwonym muszą być manualnie dozbrojone. + Пилоны, окрашенные красным, должны быть переоборудованы вручную + Pylons que estão coloridos de vermelho, precisarão ser rearmados manualmente. %1 is already configuring this aircraft! @@ -77,6 +89,8 @@ %1 konfiguriert dieses Fluggerät bereits! %1 est déjà en train de configurer cet aéronef ! %1 już konfiguruje ten pojazd! + %1 уже настраивает эту авиатехнику! + %1 já está configurando essa aeronave! Replacing pylon %1 out of %2... @@ -88,6 +102,8 @@ Ersetze Außenlaststation %1 von insgesamt %2 Remplacement du pylône %1 sur %2 ... Wymiana pylonów %1 z %2... + Замена пилона %1 из %2... + Substituindo pylon %1 de %2... Stopped at pylon %1! @@ -99,6 +115,8 @@ Gestoppt bei Außenlaststation %1 Arrêté au pylône %1 ! Zatrzymano na pylonie %1! + Остановлено на пилоне %1! + Parado no pylon %1! Vehicle too far @@ -110,6 +128,8 @@ Fahrzeug zu weit entfernt Véhicule trop éloigné Pojazd za daleko + Техника слишком далеко + Veículo muito longe Enable Pylons Menu for Zeus @@ -117,8 +137,11 @@ 啟用派龍架選單給宙斯 Abilita Menù Piloni da Zeus Zeus でパイロン メニューを有効化 + Aktiviert Außenlaststationsmenü im Zeus Activer le menu des pylônes (Zeus) Aktywuj Menu Pylonów dla Zeus'a + Активировать Меню пилонов для Зевса + Ativar Menu de Pylon para Zeus Enables use of the zeus module. @@ -126,8 +149,11 @@ 允啟使用宙斯模塊 Abilita l'uso dal modulo di Zeus Zeus モジュールでパイロン メニューを利用できます。 + Aktiviert die Nutzung im Zeus Autorise l'utilisation des modules Zeus Aktywuj wykorzystanie modułu zeus'a. + Позволяет использовать модуль Зевса + Permite usar o módulo de Zeus Enable Pylons Menu from Ammo Trucks @@ -135,8 +161,11 @@ 啟用從彈藥卡車使用派龍架選單 Abilita Menù Piloni da mezzi rifornimento munizioni 弾薬トラックからパイロン メニューを有効化 + Aktiviert Außenlaststationsmenü von Munitionstransportern Activer le menu des pylônes (camion de munitions) Aktywuj Menu Pylonów dla Ciężarówek z amunicją + Меню пилонов из грузовика боеприпасов + Ativar Menu de Pylons de Caminhões de Munição Enables use of pylons menu from ammo trucks. @@ -144,8 +173,11 @@ 允許從彈藥卡車使用派龍架選單 Abilita l'uso del Menù Piloni da mezzi rifornimento munizioni 弾薬給弾トラックからパイロン メニューを利用できます。 + Aktiviert die Nutzung von Außenlaststationsmenü von Munitionstransportern. Autorise l'utilisation du menu des pylônes depuis les camions de munitions. Aktywuj wykorzystanie menu pylonów z ciężarówek z amunicją. + Позволяет использовать меню пилонов из грузовика с боеприпасами + Permite abrir o menu de pylons através de veículos de munição. This aircraft doesn't have pylons @@ -153,8 +185,11 @@ 這架飛機沒有派龍架 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 + Эта авиатехника не имеет пилонов + Essa aeronave não possui pylons Configure pylons module is disabled for zeus @@ -162,8 +197,11 @@ 宙斯模塊的派龍架設定已被禁用 Il modulo per configurare i piloni da Zeus è disabilitato Zeus のパイロン モジュールを無効化 + Die Konfiguration für das Außenlaststationen ist im Zeus deaktiviert La configuration de pylônes est désactivé pour Zeus Konfiguracja modułu pylonów jest wyłączona dla zeus'a + Модуль Настройка пилонов отключен для Zeus + O Módulo de configurar pylons está desativado para o Zeus Rearm New Pylons @@ -175,6 +213,8 @@ Neue Außenlaststationen. aufmunitionieren Réarmer les nouveaux pylônes Dozbrój Nowe Pylony + Перевооружать новые пилоны + Rearmar novos pylons Automatically rearm new pylons from the nearest rearm vehicle. @@ -186,6 +226,8 @@ Neue Außenlaststationen. automatisch vom nächsten Munitionsfahrzeug aufmunitionieren Réarmer automatiquement tout les nouveau pylônes depuis le véhicule de munitions le plus proche. Automatycznie dozbrajaj nowe pylony z najbliższego pojazdu dozbrajania. + Автоматически перевооружать новые пилоны из ближайшей техники с боеприпасами + Automaticamente rearmas novos pylons com o veículo de munição mais próximo Time Per Pylon @@ -197,6 +239,8 @@ Zeit pro Außenlaststation Durée par pylône Czas na Pylon + Время на пилон + Tempo por pylon The time it takes to replace each pylon (in seconds). @@ -208,6 +252,8 @@ Die benötigte Zeit, um einzelne Außenlaststationen zu ersetzen (in Sekunden). Le temps nécessaire pour remplacer chaque pylône (en secondes). Czas, jaki trwa wymiana każdego z pylonów (w sekundach). + Время для замены каждого пилона (в секундах) + O tempo necessário para substituir cada pylon (em segundos) Search Distance @@ -219,6 +265,8 @@ Suchdistanz Distance de recherche Dystans Szukania + Дальность поиска + Distância de procura The distance an aircraft needs to be from a rearm vehicle. @@ -230,6 +278,8 @@ Die Distanz, die ein Fahrzeug von einem Munitionsfahrzeug entfernt sein darf. La distance à laquelle un aéronef doit être d'un véhicule de munitions. Dystans, w jakim pojazd musi być od pojazdu dozbrajania. + Дальность от авиатехники до грузовика (пункта) с боеприпасами + A distância que a aeronave precisa estar de um veículo de munições. Require Engineer @@ -241,6 +291,8 @@ Benötigt Pionier Requiert ingénieur Wymaga Mechanika + Требуется Инженер + Requer um engenheiro Require an engineer. @@ -252,6 +304,8 @@ Benötigt einen Pionier. Requiert un ingénieur. Wymaga mechanika. + Требуется роль Инженера + É necessário uma unidade definida como engenheiro para interagir com pylons. Require Toolkit @@ -263,6 +317,8 @@ Benötigt Werkzeugkasten Requiert trousse à outils Wymaga Narzędzi + Требуется Набор инструментов + Requer Kit de Ferramentas Require a toolkit in inventory. @@ -274,6 +330,8 @@ Benötigt einen Werkzeugkasten im Inventar. Requiert une trousse à outils dans l'inventaire. Wymaga narzędzi w ekwipunku. + Требуется наличие Набора инструментов в инвентаре + Requer um Kit de Ferramentas no inventário. diff --git a/addons/quickmount/XEH_postInitClient.sqf b/addons/quickmount/XEH_postInitClient.sqf index 718c08b843..23c225f583 100644 --- a/addons/quickmount/XEH_postInitClient.sqf +++ b/addons/quickmount/XEH_postInitClient.sqf @@ -4,7 +4,7 @@ if (!hasInterface) exitWith {}; ["ACE3 Movement", QGVAR(mount), [localize LSTRING(KeybindName), localize LSTRING(KeybindDescription)], "", { if (!dialog) then { - call FUNC(getInNearest); + [] call FUNC(getInNearest); }; false }] call CBA_fnc_addKeybind; diff --git a/addons/quickmount/functions/fnc_getInNearest.sqf b/addons/quickmount/functions/fnc_getInNearest.sqf index 8e8d77fe8d..b94ba8f0d9 100644 --- a/addons/quickmount/functions/fnc_getInNearest.sqf +++ b/addons/quickmount/functions/fnc_getInNearest.sqf @@ -4,7 +4,7 @@ * Mount the player in the vehicle they are directly looking at based on their distance. * * Arguments: - * None + * 0: Target (Optional) * * Return Value: * None @@ -22,17 +22,27 @@ if (!GVAR(enabled) || {ACE_player getVariable ["ace_unconscious", false]} ) exitWith {}; +params [["_interactionTarget", objNull, [objNull]]]; +TRACE_1("getInNearest",_interactionTarget); + private _start = AGLtoASL (ACE_player modelToWorldVisual (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); + _target = (_objects param [0, []]) param [2, objNull]; +}; + if (locked _target in [2,3]) exitWith { [localize LSTRING(VehicleLocked)] call EFUNC(common,displayTextStructured); true }; -TRACE_1("",_target); +TRACE_2("",_target,typeOf _target); if (!isNull _target && {alive _target} && diff --git a/addons/quickmount/stringtable.xml b/addons/quickmount/stringtable.xml index ab1bf15e67..275ec3a98e 100644 --- a/addons/quickmount/stringtable.xml +++ b/addons/quickmount/stringtable.xml @@ -10,6 +10,8 @@ 快速搭乘 Szybkie wsiadanie 빠른 탑승 + Быстрая посадка + Entrada Rápida Vehicle quick mount @@ -20,6 +22,8 @@ 快速搭乘载具 快速搭乘載具 빠른 차량 탑승 + Быстрая посадка в технику + Entrada Rápida em Veículo Quickly enter the vehicle you are directly looking at. @@ -30,6 +34,8 @@ 快速進入你正在看的載具之中 Szybko wsiądź do pojazdu, na który patrzysz. 빠르게 당신이 보고 있는 가까운 차량에 탑승합니다. + Позволяет быстро сесть в технику, на которую вы смотрите + Rapidamente entra no veículo que você está olhando diretamente. Vehicle Full @@ -40,6 +46,8 @@ 載具已滿 Pojazd pełny 만차 + Мест нет + Veículo cheio Distance @@ -50,6 +58,8 @@ 距離 Odległość 거리 + Дистанция + Distância Maximum distance to check for vehicles. @@ -60,6 +70,8 @@ 最大可檢查載具的距離 Maksymalna odległość do pojazdu. 탑승 가능한 차량과의 거리 + Максимальная дистанция для техники + Distância máxima para checar por veículos. Vehicle Locked @@ -70,6 +82,8 @@ 載具已上鎖 Pojazd zablokowany 차량 잠김 + Техника закрыта + Veículo Trancado Maximum Speed (km/h) @@ -80,6 +94,8 @@ 最高速度 (公里/小時) Maksymalna prędkość (km/h) 최대 속도 (km/h) + Макс. скорость (км/ч) + Velocidade Máxima (km/h) Maximum vehicle speed (km/h) allowed for player entry @@ -90,6 +106,8 @@ 設置玩家能在最高多少的速度之下進入載具 Maksymalna prędkość pojazdu (km/h) pozwalająca graczowi wsiąść. 플레이어가 탑승 가능한 목표 차량의 최대 속도 + Макс. скорость техники для посадки игрока (км/ч) + Velocidade máxima que o veículo pode estar para permitr entrada rápida. Prioritize Seat @@ -100,6 +118,8 @@ 優先座位 Priorytet zajmowanych pozycji 좌석 우선순위 지정 + Приоритет мест + Priorizar Assento Seat priority on entry @@ -110,13 +130,17 @@ 優先想進入哪個座位 Priorytet pozycji w pojeździe 탑승할 좌석의 우선순위를 지정합니다. + Приоритет мест при посадке + Define qual o assento que vai priorizar a Entrada Rápida Change seat + Sitz wechseln Пересесть 席の変更 Zmień zajmowaną pozycję Cambia posto + Mudar de Assento diff --git a/addons/realisticnames/CfgWeapons.hpp b/addons/realisticnames/CfgWeapons.hpp index af04d90310..acea91708c 100644 --- a/addons/realisticnames/CfgWeapons.hpp +++ b/addons/realisticnames/CfgWeapons.hpp @@ -927,4 +927,147 @@ class CfgWeapons { class hgun_Pistol_01_F: Pistol_Base_F { displayName = CSTRING(hgun_Pistol_01); }; + + // AKM + class arifle_AKM_base_F; + class arifle_AKM_F: arifle_AKM_base_F { + displayName = CSTRING(arifle_AKM); + }; + + // AKSU + class arifle_AKS_base_F; + class arifle_AKS_F: arifle_AKS_base_F { + displayName = CSTRING(arifle_AKS); + }; + + // Contact/Livonia + + // FNX-45 (Green) + class hgun_Pistol_heavy_01_green_F: hgun_Pistol_heavy_01_F { + displayName = CSTRING(hgun_Pistol_heavy_01_green_Name); + }; + + // RPG-32 (Green) + class launch_RPG32_green_F: launch_RPG32_F { + displayName = CSTRING(launch_RPG32_green_Name); + }; + + // AK15 variants + class arifle_AK12_base_F; + class arifle_AK12_F: arifle_AK12_base_F { + displayName = CSTRING(arifle_AK12); + }; + class arifle_AK12_lush_F: arifle_AK12_base_F { + displayName = CSTRING(arifle_AK12_lush); + }; + class arifle_AK12_arid_F: arifle_AK12_base_F { + displayName = CSTRING(arifle_AK12_arid); + }; + class arifle_AK12_GL_base_F; + class arifle_AK12_GL_F: arifle_AK12_GL_base_F { + displayName = CSTRING(arifle_AK12_GL); + }; + class arifle_AK12_GL_lush_F: arifle_AK12_GL_base_F { + displayName = CSTRING(arifle_AK12_GL_lush); + }; + class arifle_AK12_GL_arid_F: arifle_AK12_GL_base_F { + displayName = CSTRING(arifle_AK12_GL_arid); + }; + class arifle_AK12U_base_F; + class arifle_AK12U_F: arifle_AK12U_base_F { + displayName = CSTRING(arifle_AK12U); + }; + class arifle_AK12U_lush_F: arifle_AK12U_base_F { + displayName = CSTRING(arifle_AK12U_lush); + }; + class arifle_AK12U_arid_F: arifle_AK12U_base_F { + displayName = CSTRING(arifle_AK12U_arid); + }; + class arifle_RPK12_base_F; + class arifle_RPK12_F: arifle_RPK12_base_F { + displayName = CSTRING(arifle_RPK12); + }; + class arifle_RPK12_lush_F: arifle_RPK12_base_F { + displayName = CSTRING(arifle_RPK12_lush); + }; + class arifle_RPK12_arid_F: arifle_RPK12_base_F { + displayName = CSTRING(arifle_RPK12_arid); + }; + + // M14 (Classic) + class DMR_06_hunter_base_F; + class srifle_DMR_06_hunter_F: DMR_06_hunter_base_F { + displayName = CSTRING(srifle_DMR_06_hunter); + }; + + // Stoner 99 LMG (Black) + class LMG_Mk200_black_F: LMG_Mk200_F { + displayName = CSTRING(LMG_Mk200_black); + }; + + // MSBS Grot variants + class arifle_MSBS65_base_F; + class arifle_MSBS65_F: arifle_MSBS65_base_F { + displayName = CSTRING(arifle_MSBS65); + }; + class arifle_MSBS65_base_black_F; + class arifle_MSBS65_black_F: arifle_MSBS65_base_black_F { + displayName = CSTRING(arifle_MSBS65_black); + }; + class arifle_MSBS65_base_camo_F; + class arifle_MSBS65_camo_F: arifle_MSBS65_base_camo_F { + displayName = CSTRING(arifle_MSBS65_camo); + }; + class arifle_MSBS65_base_sand_F; + class arifle_MSBS65_sand_F: arifle_MSBS65_base_sand_F { + displayName = CSTRING(arifle_MSBS65_sand); + }; + class arifle_MSBS65_GL_base_F; + class arifle_MSBS65_GL_F: arifle_MSBS65_GL_base_F { + displayName = CSTRING(arifle_MSBS65_GL); + }; + class arifle_MSBS65_GL_base_black_F; + class arifle_MSBS65_GL_black_F: arifle_MSBS65_GL_base_black_F { + displayName = CSTRING(arifle_MSBS65_GL_black); + }; + class arifle_MSBS65_GL_base_camo_F; + class arifle_MSBS65_GL_camo_F: arifle_MSBS65_GL_base_camo_F { + displayName = CSTRING(arifle_MSBS65_GL_camo); + }; + class arifle_MSBS65_GL_base_sand_F; + class arifle_MSBS65_GL_sand_F: arifle_MSBS65_GL_base_sand_F { + displayName = CSTRING(arifle_MSBS65_GL_sand); + }; + class arifle_MSBS65_Mark_base_F; + class arifle_MSBS65_Mark_F: arifle_MSBS65_Mark_base_F { + displayName = CSTRING(arifle_MSBS65_Mark); + }; + class arifle_MSBS65_Mark_base_black_F; + class arifle_MSBS65_Mark_black_F: arifle_MSBS65_Mark_base_black_F { + displayName = CSTRING(arifle_MSBS65_Mark_black); + }; + class arifle_MSBS65_Mark_base_camo_F; + class arifle_MSBS65_Mark_camo_F: arifle_MSBS65_Mark_base_camo_F { + displayName = CSTRING(arifle_MSBS65_Mark_camo); + }; + class arifle_MSBS65_Mark_base_sand_F; + class arifle_MSBS65_Mark_sand_F: arifle_MSBS65_Mark_base_sand_F { + displayName = CSTRING(arifle_MSBS65_Mark_sand); + }; + class arifle_MSBS65_UBS_base_F; + class arifle_MSBS65_UBS_F: arifle_MSBS65_UBS_base_F { + displayName = CSTRING(arifle_MSBS65_UBS); + }; + class arifle_MSBS65_UBS_base_black_F; + class arifle_MSBS65_UBS_black_F: arifle_MSBS65_UBS_base_black_F { + displayName = CSTRING(arifle_MSBS65_UBS_black); + }; + class arifle_MSBS65_UBS_base_camo_F; + class arifle_MSBS65_UBS_camo_F: arifle_MSBS65_UBS_base_camo_F { + displayName = CSTRING(arifle_MSBS65_UBS_camo); + }; + class arifle_MSBS65_UBS_base_sand_F; + class arifle_MSBS65_UBS_sand_F: arifle_MSBS65_UBS_base_sand_F { + displayName = CSTRING(arifle_MSBS65_UBS_sand); + }; }; diff --git a/addons/realisticnames/stringtable.xml b/addons/realisticnames/stringtable.xml index 7d893e87c7..88650d8bc3 100644 --- a/addons/realisticnames/stringtable.xml +++ b/addons/realisticnames/stringtable.xml @@ -11,7 +11,7 @@ XM312 XM312 XM312 - XM312A + XM312 XM312 XM312 XM312重機槍 @@ -120,7 +120,7 @@ Poste de tir Mini-Spike (AA) Mini-Spike Odpalovač (AA) Wyrzutnia Mini-Spike (AA) - Mini-Spike Пусковое устройство (ВВ) + Mini-Spike Пусковое устройство (ПВО) Lança-mísseis Mini-Spike (AA) Mini-Spike rakétarendszer (Repülő-elhárító) Lanciatore Mini-Spike (AA) @@ -665,6 +665,8 @@ KamAZ MRL KamAZ MRL KamAZ MRL + КамАЗ РСЗО + KamAZ MRL Karatel @@ -1278,6 +1280,8 @@ Mini Granata V40 V40 小型手榴弾 Mini-granat V40 + V40 Мини-граната + Mini Granada V40 M83 Smoke Grenade (White) @@ -1514,11 +1518,29 @@ FNX-45 Tactical FNX-45 Tactical FNX-45 Tactical + FNX-45 Tactical FNX-45 タクティカル FNX-45 Tactical FNX-45戰術型手槍 FNX-45战术型手枪 + + FNX-45 Tactical (Green) + FNX-45 Tactical (Grün) + FNX-45 Tactical (Zelený) + FNX-45 Tactical (Zielony) + FNX-45 Tactical (Vert) + FNX-45 Tactical (Zöld) + FNX-45 Tactical (Verde) + FNX-45 Tactical (Зелёный) + FNX-45 Tactical (Verde) + FNX-45 Tactical (Verde) + FNX-45 Tactical (Yeşil) + FNX-45 タクティカル (緑) + FNX-45 Tactical (초록) + FNX-45戰術型手槍 (綠色) + FNX-45战术型手枪 (绿色) + Chiappa Rhino 60DS Chiappa Rhino 60DS @@ -1578,11 +1600,29 @@ РПГ-32 RPG-32 RPG-32 + RPG-32 RPG-32 RPG-32 RPG-32"哈希姆"火箭發射器 RPG-32"哈希姆"火箭发射器 + + RPG-32 (Green) + RPG-32 (Grün) + RPG-32 (Zelený) + RPG-32 (Zielony) + RPG-32 (Vert) + RPG-32 (Zöld) + RPG-32 (Verde) + РПГ-32 (Зелёный) + RPG-32 (Verde) + RPG-32 (Verde) + RPG-32 (Yeşil) + RPG-32 (緑) + RPG-32 (초록) + RPG-32"哈希姆"火箭發射器 (綠色) + RPG-32"哈希姆"火箭发射器 (绿色) + Mini-Spike (AA) Mini-Spike (FlaRak) @@ -1591,7 +1631,7 @@ Mini-Spike (AA) Mini-Spike (Repülő-elhárító) Mini-Spike (AA) - Mini-Spike (AA) + Mini-Spike (ПВО) Mini-Spike (AA) Mini-Spike (AA) ミニスパイク (対空) @@ -1607,7 +1647,7 @@ Mini-Spike (AC) Mini-Spike (Tankelhárító) Mini-Spike (AT) - Mini-Spike (AT) + Mini-Spike (ПТ) Mini-Spike (AT) Mini-Spike (AT) ミニスパイク (対地) @@ -1625,17 +1665,19 @@ Metis-M メチス-M Metis-M + Metis-M Metis-M (Brown) Metis-M (Braun) Metis-M (Brun) - Метис-М (Кори́чневый) + Метис-М (Коричневый) "麥士蒂索人"-M型反坦克導彈(棕色) "麦士蒂索人"-M型反坦克导弹(棕色) Metis-M (Marrone) メチス-M (茶) Metis-M (Brązowy) + Metis-M (Marrom) Metis-M (Green) @@ -1647,6 +1689,7 @@ Metis-M (Verde) メチス-M (緑) Metis-M (Zielony) + Metis-M (Verde) MX @@ -2648,6 +2691,8 @@ ジープ ラングラー (SPG-9) Jeep Wrangler (SPG-9) Jeep Wrangler (SPG-9) + Jeep Wrangler (СПГ-9) + Jeep Wrangler (SPG-9) Jeep Wrangler (LMG) @@ -2657,6 +2702,8 @@ ジープ ラングラー (LMG) Jeep Wrangler (LMG) Jeep Wrangler (LMG) + Jeep Wrangler (Пулемет) + Jeep Wrangler (LMG) Cessna TTx @@ -2729,7 +2776,7 @@ QBZ-95-1 (zielony hex) QBZ-95-1 (Zelený Hex) QBZ-95-1 (Hex Verte) - QBZ-95-1 (Зелёный Hex) + QBZ-95-1 (Зелёный Гекс) QBZ-95-1 (Verde Hex) QBZ-95-1 (Zöld Hex) QBZ-95-1 (Hex Verde) @@ -2745,7 +2792,7 @@ QBZ-95-1 (hex) QBZ-95-1 (Hex) QBZ-95-1 (Hex) - QBZ-95-1 (Hex) + QBZ-95-1 (Гекс) QBZ-95-1 (Hex) QBZ-95-1 (Hex) QBZ-95-1 (Hex) @@ -2777,7 +2824,7 @@ QBZ-95-1 GL (zielony hex) QBZ-95-1 GL (Zelený Hex) QBZ-95-1 GL (Hex Verte) - QBZ-95-1 GL (Зелёный Hex) + QBZ-95-1 GL (Зелёный Гекс) QBZ-95-1 GL (Verde Hex) QBZ-95-1 GL (Zöld Hex) QBZ-95-1 GL (Hex Verde) @@ -2793,7 +2840,7 @@ QBZ-95-1 GL (hex) QBZ-95-1 GL (Hex) QBZ-95-1 GL (Hex) - QBZ-95-1 GL (Hex) + QBZ-95-1 GL (Гекс) QBZ-95-1 GL (Hex) QBZ-95-1 GL (Hex) QBZ-95-1 GL (Hex) @@ -2825,7 +2872,7 @@ QBZ-95-1 LSW (zielony hex) QBZ-95-1 LSW (Zelený Hex) QBZ-95-1 LSW (Hex Verte) - QBZ-95-1 LSW (Зелёный Hex) + QBZ-95-1 LSW (Зелёный Гекс) QBZ-95-1 LSW (Verde Hex) QBZ-95-1 LSW (Zöld Hex) QBZ-95-1 LSW (Hex Verde) @@ -2841,7 +2888,7 @@ QBZ-95-1 LSW (hex) QBZ-95-1 LSW (Hex) QBZ-95-1 LSW (Hex) - QBZ-95-1 LSW (Hex) + QBZ-95-1 LSW (Гекс) QBZ-95-1 LSW (Hex) QBZ-95-1 LSW (Hex) QBZ-95-1 LSW (Hex) @@ -2873,7 +2920,7 @@ QBU-88 (zielony hex) QBU-88 (Zelený Hex) QBU-88 (Hex Verte) - QBU-88 (Зелёный Hex) + QBU-88 (Зелёный Гекс) QBU-88 (Verde Hex) QBU-88 (Zöld Hex) QBU-88 (Hex Verde) @@ -2889,7 +2936,7 @@ QBU-88 (hex) QBU-88 (Hex) QBU-88 (Hex) - QBU-88 (Hex) + QBU-88 (Гекс) QBU-88 (Hex) QBU-88 (Hex) QBU-88 (Hex) @@ -2905,7 +2952,7 @@ GM6 Lynx (Zielony hex) GM6 Lynx (Zelený Hex) GM6 Lynx (Hex Verte) - GM6 Lynx (Зелёный Hex) + GM6 Lynx (Зелёный Гекс) GM6 Lynx (Verde Hex) GM6 Lynx (Zöld Hex) GM6 Lynx (Hex Verde) @@ -3161,7 +3208,7 @@ RPG-32 (zielony hex) RPG-32 (Zelený Hex) RPG-32 (Hex Verte) - RPG-32 (Зелёный Hex) + RPG-32 (Зелёный Гекс) RPG-32 (Verde Hex) RPG-32 (Zöld Hex) RPG-32 (Hex Verde) @@ -3210,6 +3257,8 @@ "北极星"先进布署越野车 (XM312重机枪) Polaris DAGOR (XM312) Polaris DAGOR (XM312) + Polaris DAGOR (XM312) + Polaris DAGOR (XM312) Polaris DAGOR (Mini-Spike AT) @@ -3219,6 +3268,8 @@ Polaris DAGOR (Mini-Spike AT) ポラリス DAGOR (ミニスパイク対戦) Polaris DAGOR (Mini-Spike AT) + Polaris DAGOR (ПТ Mini-Spike) + Polaris DAGOR (Mini-Spike AT) Polaris DAGOR @@ -3228,6 +3279,8 @@ "北极星"先进布署越野车 Polaris DAGOR Polaris DAGOR + Polaris DAGOR + Polaris DAGOR Polaris DAGOR (light) @@ -3237,6 +3290,8 @@ "北极星"先进布署越野车 (轻型) Polaris DAGOR (leggero) Polaris DAGOR (light) + Polaris DAGOR (легкий) + Polaris DAGOR (leve) LSV Mk. II (M134) @@ -3246,6 +3301,8 @@ 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) @@ -3255,6 +3312,8 @@ LSV Mk. II (メチス-M) LSV Mk. II (Metis-M) LSV Mk. II (Metis-M) + LSV Mk. II (Метис-M) + LSV Mk. II (Metis-M) LSV Mk. II @@ -3264,6 +3323,8 @@ LSV Mk. II LSV Mk. II LSV Mk. II + LSV Mk. II + LSV Mk. II Rooikat 120 @@ -3273,6 +3334,8 @@ ルーイカット 120 Rooikat 120 Rooikat 120 + Rooikat 120 + Rooikat 120 Rooikat 120 UP @@ -3282,6 +3345,8 @@ ルーイカット 120 UP Rooikat 120 UP Rooikat 120 UP + Rooikat 120 UP + Rooikat 120 UP T-14 Armata @@ -3292,6 +3357,7 @@ T-14 アルマータ T-14 Armata T-14 Armata + T-14 Armata T-14K Armata @@ -3302,6 +3368,7 @@ T-14K アルマータ T-14K Armata T-14K Armata + T-14K Armata Wiesel 2 Ozelot (AA) @@ -3311,6 +3378,8 @@ ウィーゼル 2 オゼロット (対空) Wiesel 2 Ozelot (AA) Wiesel 2 Ozelot (AA) + Wiesel 2 Ozelot (ПВО) + Wiesel 2 Ozelot (AA) Wiesel 2 (ATGM) @@ -3320,6 +3389,8 @@ ウィーゼル 2 (ATGM) Wiesel 2 (ATGM) Wiesel 2 (ATGM) + Wiesel 2 (ПТ) + Wiesel 2 (ATGM) Wiesel 2 (MK20) @@ -3329,6 +3400,8 @@ ウィーゼル 2 (MK20) Wiesel 2 (MK20) Wiesel 2 (MK20) + Wiesel 2 (MK20) + Wiesel 2 (MK20) Wiesel 2 RFCV (Radar) @@ -3338,6 +3411,8 @@ ウィーゼル 2 (レーダー) Wiesel 2 RFCV (Radar) Wiesel 2 RFCV (Radar) + Wiesel 2 RFCV (Радар) + Wiesel 2 RFCV (Radar) Leupold Mark 4 HAMR @@ -3347,6 +3422,8 @@ Leupold Mark 4 HAMR Leupold Mark 4 HAMR Leupold Mark 4 HAMR + Leupold Mark 4 HAMR + Leupold Mark 4 HAMR Leupold Mark 4 HAMR (Khaki) @@ -3356,6 +3433,8 @@ Leupold Mark 4 HAMR (カーキ) Leupold Mark 4 HAMR (Khaki) Leupold Mark 4 HAMR (Khaki) + Leupold Mark 4 HAMR (Хаки) + Leupold Mark 4 HAMR (Khaki) ELCAN SpecterOS (Tan) @@ -3365,6 +3444,8 @@ ELCAN SpecterOS (タン) ELCAN SpecterOS (Tan) ELCAN SpecterOS (Tan) + ELCAN SpecterOS (Бронза) + ELCAN SpecterOS (Bege) ELCAN SpecterOS (Black) @@ -3374,6 +3455,8 @@ ELCAN SpecterOS (ブラック) ELCAN SpecterOS (Nero) ELCAN SpecterOS (Czarny) + ELCAN SpecterOS (Черный) + ELCAN SpecterOS (Preto) ELCAN SpecterOS (Green Hex) @@ -3382,6 +3465,8 @@ ELCAN SpecterOS (緑ヘックス) ELCAN SpecterOS (Verde Hex) ELCAN SpecterOS (Zielony Hex) + ELCAN SpecterOS (Зеленый Гекс) + ELCAN SpecterOS (Verde Hex) SIG BRAVO4 / ROMEO3 (Black) @@ -3391,6 +3476,8 @@ SIG BRAVO4 / ROMEO3 (ブラック) SIG BRAVO4 / ROMEO3 (Nero) SIG BRAVO4 / ROMEO3 (Czarny) + SIG BRAVO4 / ROMEO3 (Черный) + SIG BRAVO4 / ROMEO3 (Preto) SIG BRAVO4 / ROMEO3 (Khaki) @@ -3400,6 +3487,8 @@ SIG BRAVO4 / ROMEO3 (カーキ) SIG BRAVO4 / ROMEO3 (Khaki) SIG BRAVO4 / ROMEO3 (Khaki) + SIG BRAVO4 / ROMEO3 (Хаки) + SIG BRAVO4 / ROMEO3 (Khaki) SIG BRAVO4 / ROMEO3 (Sand) @@ -3409,6 +3498,8 @@ SIG BRAVO4 / ROMEO3 (サンド) SIG BRAVO4 / ROMEO3 (Sabbia) SIG BRAVO4 / ROMEO3 (Piasek) + SIG BRAVO4 / ROMEO3 (Песочный) + SIG BRAVO4 / ROMEO3 (Areia) Nightforce NXS @@ -3417,6 +3508,8 @@ Nightforce NXS Nightforce NXS Nightforce NXS + Nightforce NXS + Nightforce NXS Nightforce NXS (Green Hex) @@ -3425,6 +3518,8 @@ Nightforce NXS (緑ヘックス) Nightforce NXS (Verde Hex) Nightforce NXS (Zielony Hex) + Nightforce NXS (Зеленый Гекс) + Nightforce NXS (Verde Hex) Nightforce NXS (Jungle) @@ -3434,6 +3529,8 @@ Nightforce NXS (ジャングル) Nightforce NXS (Giungla) Nightforce NXS (Dżungla) + Nightforce NXS (Джунгли) + Nightforce NXS (Selva) US Optics MR-10 (Black) @@ -3442,6 +3539,8 @@ US Optics MR-10 (ブラック) US Optics MR-10 (Czarny) Ottica US MR-10 (nera) + US Optics MR-10 (Черный) + US Optics MR-10 (Preto) US Optics MR-10 (Khaki) @@ -3450,6 +3549,8 @@ US Optics MR-10 (カーキ) US Optics MR-10 (Khaki) Ottica US MR-10 (cachi) + US Optics MR-10 (Хаки) + US Optics MR-10 (Khaki) US Optics MR-10 (Sand) @@ -3458,6 +3559,8 @@ US Optics MR-10 (サンド) US Optics MR-10 (Piasek) Ottica US MR-10 (sabbia) + US Optics MR-10 (Песочный) + US Optics MR-10 (Areia) KAHLES Helia (Black) @@ -3466,6 +3569,8 @@ KAHLES ヘリア (ブラック) KAHLES Helia (Czarny) KAHLES Helia (nero) + KAHLES Helia (Черный) + KAHLES Helia (Preto) KAHLES Helia (Hex) @@ -3474,6 +3579,8 @@ KAHLES ヘリア (ヘックス) KAHLES Helia (Hex) KAHLES Helia (esagonale) + KAHLES Helia (Гекс) + KAHLES Helia (Hex) KAHLES Helia (Old) @@ -3482,6 +3589,8 @@ KAHLES ヘリア (使い古し) KAHLES Helia (Stary) KAHLES Helia (vecchio) + KAHLES Helia (Старый) + KAHLES Helia (Velho) KAHLES Helia (Tan) @@ -3490,6 +3599,8 @@ KAHLES Helia (タン) KAHLES Helia (Tan) KAHLES Helia (marroncino) + KAHLES Helia (Бронза) + KAHLES Helia (Bege) Burris XTR II @@ -3498,6 +3609,8 @@ Burris XTR II Burris XTR II Burris XTR II + Burris XTR II + Burris XTR II Burris XTR II (Green Hex) @@ -3506,6 +3619,8 @@ Burris XTR II (緑ヘックス) Burris XTR II (Green Hex) Burris XTR II (Zielony Hex) + Burris XTR II (Зеленый Гекс) + Burris XTR II (Verde Hex) EOTech XPS3 (Tan) @@ -3515,6 +3630,8 @@ EOTech XPS3 (タン) EOTech XPS3 (Tan) EOTech XPS3 (Tan) + EOTech XPS3 (Бронза) + EOTech XPS3 (Bege) EOTech XPS3 (Black) @@ -3524,6 +3641,8 @@ EOTech XPS3 (ブラック) EOTech XPS3 (Black) EOTech XPS3 (Czarny) + EOTech XPS3 (Черный) + EOTech XPS3 (Preto) EOTech XPS3 (Khaki) @@ -3533,6 +3652,8 @@ EOTech XPS3 (カーキ) EOTech XPS3 (Khaki) EOTech XPS3 (Khaki) + EOTech XPS3 (Хаки) + EOTech XPS3 (Khaki) EOTech XPS3 SMG (Tan) @@ -3542,6 +3663,8 @@ EOTech XPS3 SMG (タン) EOTech XPS3 SMG (Tan) EOTech XPS3 SMG (Tan) + EOTech XPS3 SMG (Бронза) + EOTech XPS3 SMG (Bege) EOTech XPS3 SMG (Black) @@ -3551,6 +3674,8 @@ EOTech XPS3 SMG (ブラック) EOTech XPS3 SMG (Nero) EOTech XPS3 SMG (Czarny) + EOTech XPS3 SMG (Черный) + EOTech XPS3 SMG (Preto) EOTech XPS3 SMG (Khaki) @@ -3560,6 +3685,8 @@ EOTech XPS3 SMG (カーキ) EOTech XPS3 SMG (Khaki) EOTech XPS3 SMG (Khaki) + EOTech XPS3 SMG (Хаки) + EOTech XPS3 SMG (Khaki) IOR-Valdada Pitbull 2 @@ -3568,6 +3695,8 @@ IOR-Valdada ピットブル 2 IOR-Valdada Pitbull 2 IOR-Valdada Pitbull 2 + IOR-Valdada Pitbull 2 + IOR-Valdada Pitbull 2 Burris FastFire 2 @@ -3576,6 +3705,8 @@ Burris ファストファイア 2 Burris FastFire 2 Burris FastFire 2 + Burris FastFire 2 + Burris FastFire 2 C-More Railway (Red) @@ -3585,6 +3716,8 @@ C-More レイルウェイ (赤) C-More Railway (Rosso) C-More Railway (Czerwony) + C-More Railway (Красный) + C-More Railway (Vermelho) C-More Railway (Green) @@ -3594,6 +3727,8 @@ C-More レイルウェイ (緑) C-More Railway (Verde) C-More Railway (Zielony) + C-More Railway (Зеленый) + C-More Railway (Verde) C-More Railway SMG (Red) @@ -3603,6 +3738,8 @@ C-More レイルウェイ SMG (赤) C-More Railway SMG (Rosso) C-More Railway SMG (Czerwony) + C-More Railway SMG (Красный) + C-More Railway SMG (Vermelho) C-More Railway SMG (Green) @@ -3612,6 +3749,8 @@ C-More レイルウェイ SMG (緑) C-More Railway SMG (Verde) C-More Railway SMG (Zielony) + C-More Railway SMG (Зеленый) + C-More Railway SMG (Verde) P90 TR (Black) @@ -3901,5 +4040,549 @@ 口径: 5.7mm<br />发数: 50<br />使用于: P90 구경: 5.7mm<br />장탄수: 50<br />사용됨: P90 + + AKM + AKM + AKM + AKM + AKM + AKM + AKM + AKM + AKM + AKM + AKM + AKM + AKM + AKM + AKM + + + AKS-74U + AKS-74U + AKS-74U + AKS-74U + AKS-74U + AKS-74U + AKS-74U + AKS-74U + AKS-74U + AKS-74U + AKS-74U + AKS-74U + AKS-74U + AKS-74U + AKS-74U + + + AK-15 + AK-15 + AK-15 + AK-15 + AK-15 + AK-15 + AK-15 + AK-15 + AK-15 + AK-15 + AK-15 + AK-15 + AK-15 + AK-15 + AK-15 + + + AK-15 (Lush) + AK-15 (草木茂盛) + AK-15 (Camo Forêt) + AK-15 (exuberante) + AK-15 (verdeggiante) + AK-15 (region z bujną roślinnością) + AK-15 (обильная растительность) + AK-15 (Grün) + AK-15 (bujný porost) + AK-15 (Exuberante) + AK-15 (초목) + AK-15 (繁茂) + AK-15 (緑地) + AK-15 (Gür) + AK-15 (esőerdő) + + + AK-15 (Arid) + AK-15 (乾燥氣候) + AK-15 (Camo Désert) + AK-15 (árido) + AK-15 (arido) + AK-15 (region suchy) + AK-15 (засушливая местность) + AK-15 (Trocken) + AK-15 (suchý porost) + AK-15 (Árido) + AK-15 (건조) + AK-15 (干旱) + AK-15 (乾燥地帯) + AK-15 (Kurak) + AK-15 (sivatag) + + + AK-15 GL + AK-15 GL + AK-15 GL + AK-15 GL + AK-15 GL + AK-15 GL + AK-15 GL + AK-15 GL + AK-15 GL + AK-15 GL + AK-15 GL + AK-15 GL + AK-15 GL + AK-15 GL + AK-15 GL + + + AK-15 GL (Lush) + AK-15 GL (草木茂盛) + AK-15 GL (Camo Forêt) + AK-15 GL (exuberante) + AK-15 GL (verdeggiante) + AK-15 GL (region z bujną roślinnością) + AK-15 GL (обильная растительность) + AK-15 GL (Grün) + AK-15 GL (bujný porost) + AK-15 GL (Exuberante) + AK-15 GL (초목) + AK-15 GL (繁茂) + AK-15 GL (緑地) + AK-15 GL (Gür) + AK-15 GL (esőerdő) + + + AK-15 GL (Arid) + AK-15 GL (乾燥氣候) + AK-15 GL (Camo Désert) + AK-15 GL (árido) + AK-15 GL (arido) + AK-15 GL (region suchy) + AK-15 GL (засушливая местность) + AK-15 GL (Trocken) + AK-15 GL (suchý porost) + AK-15 GL (Árido) + AK-15 GL (건조) + AK-15 GL (干旱) + AK-15 GL (乾燥地帯) + AK-15AK-15 GL (Kurak) + AK-15 GL (sivatag) + + + AK-15K + AK-15K + AK-15K + AK-15K + AK-15K + AK-15K + AK-15K + AK-15K + AK-15K + AK-15K + AK-15K + AK-15K + AK-15K + AK-15K + AK-15K + + + AK-15K (Lush) + AK-15K (草木茂盛) + AK-15K (Camo Forêt) + AK-15K (exuberante) + AK-15K (verdeggiante) + AK-15K (region z bujną roślinnością) + AK-15K (обильная растительность) + AK-15K (Grün) + AK-15K (bujný porost) + AK-15K (Exuberante) + AK-15K (초목) + AK-15K (繁茂) + AK-15K (緑地) + AK-15K (Gür) + AK-15K (esőerdő) + + + AK-15K (Arid) + AK-15K (乾燥氣候) + AK-15K (Camo Désert) + AK-15K (árido) + AK-15K (arido) + AK-15K (region suchy) + AK-15K (засушливая местность) + AK-15K (Trocken) + AK-15K (suchý porost) + AK-15K (Árido) + AK-15K (건조) + AK-15K (干旱) + AK-15K (乾燥地帯) + AK-15K (Kurak) + AK-15K (sivatag) + + + RPK + RPK + RPK + RPK + RPK + RPK + RPK + RPK + RPK + RPK + RPK + RPK + RPK + RPK + RPK + + + RPK (Lush) + RPK (草木茂盛) + RPK (Camo Forêt) + RPK (exuberante) + RPK (verdeggiante) + RPK (region z bujną roślinnością) + RPK (обильная растительность) + RPK (Grün) + RPK (bujný porost) + RPK (Exuberante) + RPK (초목) + RPK (繁茂) + RPK (緑地) + RPK (Gür) + RPK (esőerdő) + + + RPK (Arid) + RPK (乾燥氣候) + RPK (Camo Désert) + RPK (árido) + RPK (arido) + RPK (region suchy) + RPK (засушливая местность) + RPK (Trocken) + RPK (suchý porost) + RPK (Árido) + RPK (건조) + RPK (干旱) + RPK (乾燥地帯) + RPK (Kurak) + RPK (sivatag) + + + M14 (classic) + M14 (经典) + M14 (classique) + M14 (clásico) + M14 (classico) + M14 (klasyczny) + M14 (классический) + M14 (klassisch) + M14 (klasický) + M14 (clássico) + M14 (표준) + M14 (經典) + M14 (クラシック) + M14 (klasik) + M14 (klasszikus) + + + Stoner 99 LMG (Black) + 斯通納99輕機槍(黑色) + Stoner 99 LMG (Noir) + Stoner 99 LMG (Negro) + Stoner 99 LMG (Nero) + Stoner 99 LMG (Czarny) + Stoner 99 LMG (Чёрный) + Stoner 99 LMG (Schwarz) + Stoner 99 LMG (Černá) + Stoner 99 LMG (Preto) + Stoner 99 LMG (검정) + 斯通纳99轻机枪(黑色) + ストーナー 99 LMG(ブラック) + Stoner 99 LMG (Siyah) + Stoner 99 Könnyűgéppuska (Fekete) + + + MSBS Grot + MSBS Grot + MSBS Grot + MSBS Grot + MSBS Grot + MSBS Grot + MSBS Grot + MSBS Grot + MSBS Grot + MSBS Grot + MSBS Grot + MSBS Grot + MSBS Grot + MSBS Grot + MSBS Grot + + + MSBS Grot (Black) + MSBS Grot(黑色) + MSBS Grot (Noir) + MSBS Grot (Negro) + MSBS Grot (Nero) + MSBS Grot (Czarny) + MSBS Grot (Чёрный) + MSBS Grot (Schwarz) + MSBS Grot (Černá) + MSBS Grot (Preto) + MSBS Grot (검정) + MSBS Grot(黑色) + MSBS Grot(ブラック) + MSBS Grot (Siyah) + MSBS Grot (Fekete) + + + MSBS Grot (Camo) + MSBS Grot(迷彩) + MSBS Grot (Camo) + MSBS Grot (Camuflaje) + MSBS Grot (Camo) + MSBS Grot (Kamuflaż) + MSBS Grot (Камо) + MSBS Grot (Tarnmuster) + MSBS Grot (Kamufláž) + MSBS Grot (Camo) + MSBS Grot (위장) + MSBS Grot(迷彩) + MSBS Grot (カモフラージュ) + MSBS Grot (Kamuflaj) + MSBS Grot (Terepmintás) + + + MSBS Grot (Sand) + MSBS Grot(沙色) + MSBS Grot (Sable) + MSBS Grot (Arena) + MSBS Grot (Sabbia) + MSBS Grot (Piaskowy) + MSBS Grot (Песочный) + MSBS Grot (Sandfarben) + MSBS Grot (Písková) + MSBS Grot (Deserto) + MSBS Grot (모래) + MSBS Grot(沙色) + MSBS Grot (サンド) + MSBS Grot (Kum) + MSBS Grot (Homok) + + + MSBS Grot GL + MSBS Grot GL + MSBS Grot GL + MSBS Grot GL + MSBS Grot GL + MSBS Grot GL + MSBS Grot GL + MSBS Grot GL + MSBS Grot GL + MSBS Grot GL + MSBS Grot GL + MSBS Grot GL + MSBS Grot GL + MSBS Grot GL + MSBS Grot GL + + + MSBS Grot GL (Black) + MSBS Grot GL(黑色) + MSBS Grot GL (Noir) + MSBS Grot GL (Negro) + MSBS Grot GL (Nero) + MSBS Grot GL (Czarny) + MSBS Grot GL (Чёрный) + MSBS Grot GL (Schwarz) + MSBS Grot GL (Černá) + MSBS Grot GL (Preto) + MSBS Grot GL (검정) + MSBS Grot GL(黑色) + MSBS Grot GL(ブラック) + MSBS Grot GL (Siyah) + MSBS Grot GL (Fekete) + + + MSBS Grot GL (Camo) + MSBS Grot GL(迷彩) + MSBS Grot GL (Camo) + MSBS Grot GL (Camuflaje) + MSBS Grot GL (Camo) + MSBS Grot GL (Kamuflaż) + MSBS Grot GL (Камо) + MSBS Grot GL (Tarnmuster) + MSBS Grot GL (Kamufláž) + MSBS Grot GL (Camo) + MSBS Grot GL (위장) + MSBS Grot GL(迷彩) + MSBS Grot GL (カモフラージュ) + MSBS Grot GL (Kamuflaj) + MSBS Grot GL (Terepmintás) + + + MSBS Grot GL (Sand) + MSBS Grot GL(沙色) + MSBS Grot GL (Sable) + MSBS Grot GL (Arena) + MSBS Grot GL (Sabbia) + MSBS Grot GL (Piaskowy) + MSBS Grot GL (Песочный) + MSBS Grot GL (Sandfarben) + MSBS Grot GL (Písková) + MSBS Grot GL (Deserto) + MSBS Grot GL (모래) + MSBS Grot GL(沙色) + MSBS Grot GL (サンド) + MSBS Grot GL (Kum) + MSBS Grot GL (Homok) + + + MSBS Grot MR + MSBS Grot MR + MSBS Grot MR + MSBS Grot MR + MSBS Grot MR + MSBS Grot MR + MSBS Grot MR + MSBS Grot MR + MSBS Grot MR + MSBS Grot MR + MSBS Grot MR + MSBS Grot MR + MSBS Grot MR + MSBS Grot MR + MSBS Grot MR + + + MSBS Grot MR (Black) + MSBS Grot MR(黑色) + MSBS Grot MR (Noir) + MSBS Grot MR (Negro) + MSBS Grot MR (Nero) + MSBS Grot MR (Czarny) + MSBS Grot MR (Чёрный) + MSBS Grot MR (Schwarz) + MSBS Grot MR (Černá) + MSBS Grot MR (Preto) + MSBS Grot MR (검정) + MSBS Grot MR(黑色) + MSBS Grot MR(ブラック) + MSBS Grot MR (Siyah) + MSBS Grot MR (Fekete) + + + MSBS Grot MR (Camo) + MSBS Grot MR(迷彩) + MSBS Grot MR (Camo) + MSBS Grot MR (Camuflaje) + MSBS Grot MR (Camo) + MSBS Grot MR (Kamuflaż) + MSBS Grot MR (Камо) + MSBS Grot MR (Tarnmuster) + MSBS Grot MR (Kamufláž) + MSBS Grot MR (Camo) + MSBS Grot MR (위장) + MSBS Grot MR(迷彩) + MSBS Grot MR (カモフラージュ) + MSBS Grot MR (Kamuflaj) + MSBS Grot MR (Terepmintás) + + + MSBS Grot MR (Sand) + MSBS Grot MR(沙色) + MSBS Grot MR (Sable) + MSBS Grot MR (Arena) + MSBS Grot MR (Sabbia) + MSBS Grot MR (Piaskowy) + MSBS Grot MR (Песочный) + MSBS Grot MR (Sandfarben) + MSBS Grot MR (Písková) + MSBS Grot MR (Deserto) + MSBS Grot MR (모래) + MSBS Grot MR(沙色) + MSBS Grot MR (サンド) + MSBS Grot MR (Kum) + MSBS Grot MR (Homok) + + + MSBS Grot SG + MSBS Grot SG + MSBS Grot SG + MSBS Grot SG + MSBS Grot SG + MSBS Grot SG + MSBS Grot SG + MSBS Grot SG + MSBS Grot SG + MSBS Grot SG + MSBS Grot SG + MSBS Grot SG + MSBS Grot SG + MSBS Grot SG + MSBS Grot SG + + + MSBS Grot SG (Black) + MSBS Grot SG(黑色) + MSBS Grot SG (Noir) + MSBS Grot SG (Negro) + MSBS Grot SG (Nero) + MSBS Grot SG (Czarny) + MSBS Grot SG (Чёрный) + MSBS Grot SG (Schwarz) + MSBS Grot SG (Černá) + MSBS Grot SG (Preto) + MSBS Grot SG (검정) + MSBS Grot SG(黑色) + MSBS Grot SG(ブラック) + MSBS Grot SG (Siyah) + MSBS Grot SG (Fekete) + + + MSBS Grot SG (Camo) + MSBS Grot SG(迷彩) + MSBS Grot SG (Camo) + MSBS Grot SG (Camuflaje) + MSBS Grot SG (Camo) + MSBS Grot SG (Kamuflaż) + MSBS Grot SG (Камо) + MSBS Grot SG (Tarnmuster) + MSBS Grot SG (Kamufláž) + MSBS Grot SG (Camo) + MSBS Grot SG (위장) + MSBS Grot SG(迷彩) + MSBS Grot SG (カモフラージュ) + MSBS Grot SG (Kamuflaj) + MSBS Grot SG (Terepmintás) + + + MSBS Grot SG (Sand) + MSBS Grot SG(沙色) + MSBS Grot SG (Sable) + MSBS Grot SG (Arena) + MSBS Grot SG (Sabbia) + MSBS Grot SG (Piaskowy) + MSBS Grot SG (Песочный) + MSBS Grot SG (Sandfarben) + MSBS Grot SG (Písková) + MSBS Grot SG (Deserto) + MSBS Grot SG (모래) + MSBS Grot SG(沙色) + MSBS Grot SG (サンド) + MSBS Grot SG (Kum) + MSBS Grot SG (Homok) + diff --git a/addons/rearm/functions/fnc_addRearmActions.sqf b/addons/rearm/functions/fnc_addRearmActions.sqf index 79b976f322..480cc90007 100644 --- a/addons/rearm/functions/fnc_addRearmActions.sqf +++ b/addons/rearm/functions/fnc_addRearmActions.sqf @@ -5,38 +5,44 @@ * * Arguments: * 0: Ammo Truck + * 1: Player * * Return Value: * ChildActions * * Example: - * [tank] call ace_rearm_fnc_addRearmActions + * [tank, player] call ace_rearm_fnc_addRearmActions * * Public: No */ -params ["_truck"]; +params ["_truck", "_player"]; -private _vehicles = nearestObjects [_truck, ["AllVehicles"], 20]; +private _vehicles = nearestObjects [_truck, ["AllVehicles"], GVAR(distance)]; _vehicles = _vehicles select {(_x != _truck) && {!(_x isKindOf "CAManBase")} && {!(_x getVariable [QGVAR(disabled), false])}}; -if (missionNamespace getVariable [QEGVAR(mk6mortar,useAmmoHandling), false]) then { - _vehicles = _vehicles select {!(_x isKindOf "Mortar_01_base_F")}; -}; - +private _cswCarryMagazines = []; private _vehicleActions = []; { private _vehicle = _x; - + // Array of magazines that can be rearmed in the vehicle private _needRearmMags = ([_vehicle] call FUNC(getNeedRearmMagazines)) apply {_x select 0}; - + // _needRearmMags without duplicates private _magazineHelper = _needRearmMags arrayIntersect _needRearmMags; _magazineHelper = _magazineHelper select {[_truck, _x] call FUNC(hasEnoughSupply)}; + + if (["ace_csw"] call EFUNC(common,isModLoaded)) then { + ([_vehicle] call EFUNC(csw,aceRearmGetCarryMagazines)) params ["_turretMagsCSW", "_allCarryMags"]; + TRACE_3("csw compat",_vehicle,_turretMagsCSW,_allCarryMags); + _cswCarryMagazines append _allCarryMags; + _magazineHelper = _magazineHelper - _turretMagsCSW; + }; + TRACE_2("can add",_x,_magazineHelper); - + if (!(_magazineHelper isEqualTo [])) then { private _icon = getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "Icon"); if !((_icon select [0, 1]) == "\") then { @@ -80,10 +86,29 @@ private _vehicleActions = []; {}, [] ] call EFUNC(interact_menu,createAction); - + _vehicleActions pushBack [_action, _actions, _truck]; }; }; } forEach _vehicles; +if (!(_cswCarryMagazines isEqualTo [])) then { + _cswCarryMagazines = _cswCarryMagazines arrayIntersect _cswCarryMagazines; + _cswCarryMagazines = _cswCarryMagazines select {[_truck, _x] call FUNC(hasEnoughSupply)}; + private _baseAction = [QGVAR(cswTake), "CSW", "", {}, {true}] call EFUNC(interact_menu,createAction); + private _subActions = _cswCarryMagazines apply { + private _action = [ + _x, + _x call FUNC(getMagazineName), + getText(configFile >> "CfgMagazines" >> _x >> "picture"), + {_this call FUNC(takeAmmo)}, + {true}, + {}, + [_x, _player] + ] call EFUNC(interact_menu,createAction); + [_action, [], _truck]; + }; + _vehicleActions pushBack [_baseAction, _subActions, _truck]; +}; + _vehicleActions diff --git a/addons/rearm/functions/fnc_getMagazineName.sqf b/addons/rearm/functions/fnc_getMagazineName.sqf index 1871cedbf7..f83d71e470 100644 --- a/addons/rearm/functions/fnc_getMagazineName.sqf +++ b/addons/rearm/functions/fnc_getMagazineName.sqf @@ -26,6 +26,8 @@ if (isNil "_magName") then { WARNING_1("Magazine is missing display name [%1]",_className); }; + if ((_displayName select [0,6]) == "[CSW] ") then { _displayName = _displayName select [6]; }; + GVAR(magazineNameCache) setVariable [_className, _displayName]; GVAR(originalMagazineNames) pushBack _displayName; TRACE_2("Adding to cache",_className,_displayName); diff --git a/addons/rearm/functions/fnc_getNeedRearmMagazines.sqf b/addons/rearm/functions/fnc_getNeedRearmMagazines.sqf index e2a06075d5..9dbcf463eb 100644 --- a/addons/rearm/functions/fnc_getNeedRearmMagazines.sqf +++ b/addons/rearm/functions/fnc_getNeedRearmMagazines.sqf @@ -33,19 +33,19 @@ private _magazineInfo = []; private _pylonConfigs = configProperties [configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "Components" >> "TransportPylonsComponent" >> "Pylons", "isClass _x"]; { private _pylonConfig = _x; - + // Strangely, a 1-based index. private _pylonIndex = _forEachIndex + 1; - + // Retrieving pylon magazine by index. If the pylon is empty, it is marked with "". private _pylonMagazine = (getPylonMagazines _vehicle) select (_pylonIndex - 1); - + // Only care about pylons that have a magazine. if (!(_pylonMagazine isEqualTo "")) then { - + private _maxRounds = getNumber (configFile >> "CfgMagazines" >> _pylonMagazine >> "count"); private _currentRounds = _vehicle ammoOnPylon _pylonIndex; - + if (_currentRounds < _maxRounds) then { // getPylonTurret expects 0 based index, and returns driver turret as [-1] private _pylonTurret = [_vehicle, (_pylonIndex - 1)] call EFUNC(common,getPylonTurret); @@ -62,13 +62,13 @@ private _turrets = [_vehicle] call FUNC(getAllRearmTurrets); // _magazines without duplicates private _magazineClasses = _magazines arrayIntersect _magazines; - + { private _magazineClass = _x; - + private _maxMagazines = [_vehicle, _turretPath, _magazineClass] call FUNC(getMaxMagazines); private _maxRoundsPerMag = getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "count"); - + /* Array of ammo counts in every magazine. Example: [200, 200, 152] means 2 mags with 200 * rounds and 1 mag with 152 rounds. */ private _currentRounds = [_vehicle, _turretPath, _magazineClass] call FUNC(getTurretMagazineAmmo); @@ -77,9 +77,10 @@ private _turrets = [_vehicle] call FUNC(getAllRearmTurrets); /* If there is space for new magazines or if some magazines are not full, add the magazine * type to _magazineInfo. */ if ((_currentMagazines < _maxMagazines) || {({_x < _maxRoundsPerMag} count _currentRounds) > 0}) then { + if (_magazineClass == "FakeWeapon") exitWith {}; _magazineInfo pushBack [_magazineClass, _turretPath, false, -1, _maxMagazines, _currentMagazines, _maxRoundsPerMag, _currentRounds]; }; - + } forEach _magazineClasses; } forEach _turrets; diff --git a/addons/rearm/functions/fnc_rearm.sqf b/addons/rearm/functions/fnc_rearm.sqf index 2556096c11..6b5a3da12c 100644 --- a/addons/rearm/functions/fnc_rearm.sqf +++ b/addons/rearm/functions/fnc_rearm.sqf @@ -46,7 +46,7 @@ private _magazineDisplayName = _magazineClass call FUNC(getMagazineName); format [localize LSTRING(RearmAction), getText(configFile >> "CfgVehicles" >> (typeOf _target) >> "displayName"), _magazineDisplayName], { param [0] params ["_target", "_unit"]; - (_unit distanceSqr _target) <= REARM_ACTION_DISTANCE_SQR + _player distance _target <= GVAR(distance); }, ["isnotinside"] ] call EFUNC(common,progressBar); diff --git a/addons/rearm/functions/fnc_rearmEntireVehicle.sqf b/addons/rearm/functions/fnc_rearmEntireVehicle.sqf index b3147f976c..df06d384d4 100644 --- a/addons/rearm/functions/fnc_rearmEntireVehicle.sqf +++ b/addons/rearm/functions/fnc_rearmEntireVehicle.sqf @@ -28,7 +28,7 @@ TRACE_3("rearmEntireVehicle",_truck,_player,_vehicle); format [localize LSTRING(BasicRearmAction), getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName")], { param [0] params ["", "_vehicle", "_player"]; - (_player distanceSqr _vehicle) <= REARM_ACTION_DISTANCE_SQR + _player distance _vehicle <= GVAR(distance); }, ["isnotinside"] ] call EFUNC(common,progressBar); diff --git a/addons/rearm/functions/fnc_rearmEntireVehicleSuccessLocal.sqf b/addons/rearm/functions/fnc_rearmEntireVehicleSuccessLocal.sqf index 6d48cd338f..8bf8244dd7 100644 --- a/addons/rearm/functions/fnc_rearmEntireVehicleSuccessLocal.sqf +++ b/addons/rearm/functions/fnc_rearmEntireVehicleSuccessLocal.sqf @@ -22,6 +22,14 @@ TRACE_3("rearmEntireVehicleSuccessLocal",_truck,_vehicle,_turretPath); // Fetching all rearmable magazines in this turret private _magazines = ([_vehicle] call FUNC(getNeedRearmMagazines)) select {(_x select 1) isEqualTo _turretPath}; +if (["ace_csw"] call EFUNC(common,isModLoaded)) then { + ([_vehicle, _turretPath] call EFUNC(csw,aceRearmGetCarryMagazines)) params ["_turretMagsCSW", "_allCarryMags"]; + TRACE_1("skipping",_turretMagsCSW); + _magazines = _magazines select { + _x params ["_magazineClass"]; + (_turretMagsCSW findIf {_x == _magazineClass}) == -1 + }; +}; { _x params ["_magazineClass", "_magTurretPath", "_isPylonMag", "_pylonIndex", "_maxMagazines", "_currentMagazines", "_maxRoundsPerMag", "_currentRounds"]; diff --git a/addons/rearm/functions/fnc_setTurretMagazineAmmo.sqf b/addons/rearm/functions/fnc_setTurretMagazineAmmo.sqf index 984d382e08..c2abe8a132 100644 --- a/addons/rearm/functions/fnc_setTurretMagazineAmmo.sqf +++ b/addons/rearm/functions/fnc_setTurretMagazineAmmo.sqf @@ -30,7 +30,7 @@ private _magLoadedInWeapon = false; private _loadedWeapon = ""; { private _currentlyLoadedMag = (weaponState [_vehicle, _turretPath, _x]) select 3; - + if (_currentlyLoadedMag isEqualTo _magazineClass) exitWith { _magLoadedInWeapon = true; _loadedWeapon = _x; @@ -47,37 +47,36 @@ if (!_magLoadedInWeapon) then { { _vehicle addMagazineTurret [_magazineClass, _turretPath, _x]; } forEach _ammoCounts; - } else { /* Special hack case: * The magazine class was loaded into a weapon. If the weapon has more than one type of * magazine (e.g. AP and HEAT in a cannon), then removing all magazines would trigger the * weapon to load a different magazine type. For example, removing the HEAT shells while HEAT * is loaded makes the cannon switch to AP. - * + * * To prevent that, we must remove all magazines that would fit into the weapon and then add * them back with the magazine-to-be-loaded being the first. */ - private _allowedMagClassesInWeapon = getArray (configFile >> "CfgWeapons" >> _loadedWeapon >> "magazines"); - + private _allowedMagClassesInWeapon = [_loadedWeapon] call CBA_fnc_compatibleMagazines; + /* Current ammo counts of all allowed magazine classes in weapon. * Example: [["8Rnd_82mm_Mo_shells", [8, 8, 2]], ["8Rnd_82mm_Mo_Flare_white", [7]]] */ private _ammoCountsByMagClass = _allowedMagClassesInWeapon apply {[_x, ([_vehicle, _turretPath, _x] call FUNC(getTurretMagazineAmmo))]}; - + // Removing all magazines that fit into the weapon. { _vehicle removeMagazinesTurret [_x, _turretPath]; } forEach _allowedMagClassesInWeapon; - + // Adding the mags of the given class first with updated ammo counts. { _vehicle addMagazineTurret [_magazineClass, _turretPath, _x]; } forEach _ammoCounts; - + // Adding back all other magazines with their original ammo counts. { _x params ["_loopMagClass", "_loopAmmoCounts"]; - + if (!(_loopMagClass isEqualTo _magazineClass)) then { { _vehicle addMagazineTurret [_loopMagClass, _turretPath, _x]; diff --git a/addons/rearm/functions/fnc_takeAmmo.sqf b/addons/rearm/functions/fnc_takeAmmo.sqf index f4a7339edc..1c1e325de8 100644 --- a/addons/rearm/functions/fnc_takeAmmo.sqf +++ b/addons/rearm/functions/fnc_takeAmmo.sqf @@ -8,7 +8,7 @@ * 1: Unit * 2: Params * 0: Magazine Classname - * 1: Vehicle to be armed + * 1: Vehicle to be armed or player * * Return Value: * None @@ -27,12 +27,18 @@ TRACE_5("takeAmmo",_truck,_unit,_args,_magazineClass,_vehicle); REARM_HOLSTER_WEAPON; +private _targetName = if (_vehicle == _unit) then { + "CSW" +} else { + getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName") +}; + [ TIME_PROGRESSBAR(REARM_DURATION_TAKE select _idx), - [_unit, _magazineClass, _truck], + [_unit, _magazineClass, _truck, _vehicle], FUNC(takeSuccess), "", - format [localize LSTRING(TakeAction), _magazineClass call FUNC(getMagazineName), getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName")], + format [localize LSTRING(TakeAction), _magazineClass call FUNC(getMagazineName), _targetName], {true}, ["isnotinside"] ] call EFUNC(common,progressBar); diff --git a/addons/rearm/functions/fnc_takeSuccess.sqf b/addons/rearm/functions/fnc_takeSuccess.sqf index 3986b21484..e00d430f99 100644 --- a/addons/rearm/functions/fnc_takeSuccess.sqf +++ b/addons/rearm/functions/fnc_takeSuccess.sqf @@ -8,19 +8,20 @@ * 0: Unit * 1: Magazine Classname * 2: Ammo Truck + * 3: Target Vehicle or Player * * Return Value: * None * * Example: - * [[player, "500Rnd_127x99_mag_Tracer_Red"]] call ace_rearm_fnc_takeSuccess + * [[player, "500Rnd_127x99_mag_Tracer_Red", ammoTruck, targetVehicle]] call ace_rearm_fnc_takeSuccess * * Public: No */ params ["_args"]; -_args params ["_unit", "_magazineClass", "_truck"]; -TRACE_3("takeSuccess",_unit,_magazineClass,_truck); +_args params ["_unit", "_magazineClass", "_truck", "_vehicle"]; +TRACE_4("takeSuccess",_unit,_magazineClass,_truck,_vehicle); private _success = true; if (GVAR(supply) > 0) then { @@ -28,6 +29,13 @@ if (GVAR(supply) > 0) then { }; if !(_success) exitWith {WARNING_2("takeSuccess failed to take [%1] from [%2]",_magazineClass,_truck);}; +if (_vehicle == _unit) exitWith { + ([_magazineClass] call FUNC(getCaliber)) params ["", "_idx"]; + private _rounds = (REARM_COUNT select _idx); + TRACE_4("passing to csw",_unit,_magazineClass,_idx,_rounds); + [_unit, _magazineClass, _rounds] call EFUNC(csw,reload_handleReturnAmmo); +}; + [_unit, "forceWalk", "ACE_rearm", true] call EFUNC(common,statusEffect_set); [_unit, "blockThrow", "ACE_rearm", true] call EFUNC(common,statusEffect_set); private _dummy = [_unit, _magazineClass] call FUNC(createDummy); diff --git a/addons/rearm/initSettings.sqf b/addons/rearm/initSettings.sqf index 0e5e421747..3cac2fead7 100644 --- a/addons/rearm/initSettings.sqf +++ b/addons/rearm/initSettings.sqf @@ -17,3 +17,12 @@ true, // isGlobal {[QGVAR(supply), _this] call EFUNC(common,cbaSettings_settingChanged)} ] call CBA_settings_fnc_init; + +[ + QGVAR(distance), "SLIDER", + [localize LSTRING(RearmSettings_distance_DisplayName), localize LSTRING(RearmSettings_distance_Description)], + [localize ELSTRING(OptionsMenu,CategoryLogistics), localize LSTRING(DisplayName)], + [10, 50, 20, 0], + true, // isGlobal + {[QGVAR(supply), _this] call EFUNC(common,cbaSettings_settingChanged)} +] call CBA_settings_fnc_init; diff --git a/addons/rearm/stringtable.xml b/addons/rearm/stringtable.xml index 31210642f4..e2ad75a5de 100644 --- a/addons/rearm/stringtable.xml +++ b/addons/rearm/stringtable.xml @@ -10,6 +10,8 @@ 再武装 Réarmement Dozbrajanie + Перевооружение + Rearme Rearm Settings @@ -45,7 +47,7 @@ Rearm Amount Aufmunitioniermenge Szybkość dozbrajania - Количество вооружения + Степень перевооружения Quantidade de rearme Rychlost přezbrojení Ammontare Riarmo @@ -60,7 +62,7 @@ How fast should a vehicle be rearmed? Wie schnell soll ein Fahrzeug aufmunitioniert werden? Jak szybko pojazd zostanie dozbrajania? - Как быстро техника должна перевооружаться? + Насколько быстро должна перевооружаться техника? Quão rápido o veículo deve ser rearmado? Jak rychle bude vozidlo přezbrojeno? Quanto velocemente dovrebbe essere riarmato un veicolo? @@ -75,7 +77,7 @@ Entire Vehicle Gesamtes Fahrzeug Cały pojazd - Полностью техника + Техника полностью Todo o veículo Celé vozidlo Tutto il Veicolo @@ -90,7 +92,7 @@ Entire Magazine Gesamtes Magazin Cały magazynek - Полный магазин + Магазин полностью Todo o carregador Celý zásobník Tutto il Caricatore @@ -105,7 +107,7 @@ Amount based on caliber Kaliberbasierte Anzahl Ilość zależna od kalibru - Количество зависит от калибра + В зависимости от калибра Quantidade baseada no calibre Rychlost závisí na ráži Ammontare basato sul calibro @@ -126,6 +128,8 @@ Zapas amunicji 탄약 보급 Approvisionnement en munitions + Запас боеприпасов + Suprimento de Munições How much ammunition does an ammo truck carry? @@ -137,6 +141,8 @@ Ile amunicji przewozi ciężarówka? 탄약 차량은 얼마나 많은 양의 탄약을 가질 수 있음? Quelle quantité de munitions un camion doit-il transporter ? + Какой боезапас перевозит грузовик с боеприпасами? + Quanta munição um caminhão de munições carrega? Unlimited ammo supply @@ -148,6 +154,8 @@ Nielimitowany zapas amunicji 무한의 탄약 Approvisionnement en munitions illimité + Неограниченный боезапас + Suprimento Ilimitado de Munição Limited ammo supply based on caliber @@ -159,6 +167,8 @@ Zapas amunicji zależny od kalibru 구경에 따라 제한된 탄약 Approvisionnement en munitions limité basé sur le calibre. + Ограниченный боезапас в зависимости от калибра + Munição Limitada ao Calibre Only specific Magazines @@ -170,6 +180,8 @@ Tylko konkretne magazynki 특정 탄약만 Seulement des chargeurs spécifiques + Только определенные магазины + Apenas carregadores específicos Check remaining ammunition @@ -181,6 +193,8 @@ Sprawdź ilość amunicji 남은 탄약 확인 Vérifier les munitions restantes + Проверить остаток БК + Checar munição restante Checking remaining ammunition... @@ -192,6 +206,8 @@ Sprawdzanie ilości amunicji... 남은 탄약 확인중... Vérification des munitions restantes... + Проверка остатка боекомплекта... + Checando Munição... There is ammunition worth %1 points left. @@ -203,6 +219,8 @@ Pozostało %1 punktów amunicji. 여기에는 최소 %1 포인트의 탄약이 남았습니다. Il reste des munitions d'une valeur de %1 points. + Остаток единиц БК: %1 + Possui munição equivalente a %1 pontos restantes. The following ammunition is left:%1 @@ -214,6 +232,8 @@ Pozostała amunicja: %1 다음의 탄약이 남음 : %1 Il reste les munitions suivantes %1 + Оставшийся боекомплект: %1 + A munição que restou: %1 There is no ammunition left. @@ -225,6 +245,8 @@ Brak amunicji w zapasie. 여기에는 탄약이 남지 않았습니다. Il n'y a plus de munitions + Запас боекомплекта пуст + Não há munição sobrando. Rearm @@ -591,6 +613,8 @@ 再武装用カーゴ Ładunek Dozbrajający Rifornimento Munizioni + Боеприпасы для перевооружения + Carga de Rearme The cargo for rearming (-1 disable) @@ -598,6 +622,20 @@ カーゴからの再武装 (-1 で無効化) Ładunek do dozbrajania (-1 wyłączy) Il rifornimento delle munizioni (-1 per disabilitarlo) + Объем боеприпасов для перевооружения (-1 для отмены) + A Carga para Rearmamento (-1 para desativar) + + + Rearm distance + Distance de réarmement + Aufrüstbereich + Distância para Rearmar + + + The maximum distance a vehicle can be rearmed at + Distance maximale à laquelle un véhicle 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. diff --git a/addons/refuel/functions/fnc_refuel.sqf b/addons/refuel/functions/fnc_refuel.sqf index 4717f1206c..f3e042cd56 100644 --- a/addons/refuel/functions/fnc_refuel.sqf +++ b/addons/refuel/functions/fnc_refuel.sqf @@ -93,6 +93,8 @@ if (_maxFuel == 0) then { }; _unit setVariable [QGVAR(tempFuel), _fuelInSink]; + [QGVAR(tick), [_source, _sink, _rateTime]] call CBA_fnc_localEvent; + [QEGVAR(common,setFuel), [_sink, _fuelInSink], _sink] call CBA_fnc_targetEvent; [_source, _fuelInSource] call FUNC(setFuel); } else { @@ -100,6 +102,7 @@ if (_maxFuel == 0) then { }; if (_finished) exitWith { + [QGVAR(stopped), [_source, _sink]] call CBA_fnc_localEvent; _nozzle setVariable [QGVAR(lastTickMissionTime), nil]; _nozzle setVariable [QGVAR(isRefueling), false, true]; }; diff --git a/addons/refuel/functions/fnc_turnOff.sqf b/addons/refuel/functions/fnc_turnOff.sqf index 1448a0d145..6b5f17a95d 100644 --- a/addons/refuel/functions/fnc_turnOff.sqf +++ b/addons/refuel/functions/fnc_turnOff.sqf @@ -21,3 +21,4 @@ params [["_unit", objNull, [objNull]], ["_nozzle", objNull, [objNull]]]; _nozzle setVariable [QGVAR(lastTickMissionTime), nil]; _nozzle setVariable [QGVAR(isRefueling), false, true]; [LSTRING(Hint_Stopped), 1.5, _unit] call EFUNC(common,displayTextStructured); +[QGVAR(stopped), [_nozzle getVariable QGVAR(source), _nozzle getVariable QGVAR(sink)]] call CBA_fnc_localEvent; diff --git a/addons/refuel/functions/fnc_turnOn.sqf b/addons/refuel/functions/fnc_turnOn.sqf index 4cbbc0033d..b96cc6cda4 100644 --- a/addons/refuel/functions/fnc_turnOn.sqf +++ b/addons/refuel/functions/fnc_turnOn.sqf @@ -21,3 +21,4 @@ params [["_unit", objNull, [objNull]], ["_nozzle", objNull, [objNull]]]; _nozzle setVariable [QGVAR(lastTickMissionTime), CBA_missionTime]; _nozzle setVariable [QGVAR(isRefueling), true, true]; [LSTRING(Hint_Started), 1.5, _unit] call EFUNC(common,displayTextStructured); +[QGVAR(started), [_nozzle getVariable QGVAR(source), _nozzle getVariable QGVAR(sink)]] call CBA_fnc_localEvent; diff --git a/addons/refuel/stringtable.xml b/addons/refuel/stringtable.xml index 19a22dc390..359155a521 100644 --- a/addons/refuel/stringtable.xml +++ b/addons/refuel/stringtable.xml @@ -280,6 +280,8 @@ 无法开启燃料喷嘴 주유기를 켤 수 없습니다. Nie można włączyć dyszy paliwowej + Не удалось включить топливный пистолет + Não foi possível ativar o bico de combustível %1 Liters fueled @@ -441,6 +443,8 @@ 加油軟管長度 Długość węża paliwowego 주유기 호스 길이 + Длина заправочного шланга + Comprimento da Mangueira de Combustível Fuel Cargo Volume @@ -452,6 +456,7 @@ 储油量 연료통 크기 Pojemność Ładunku Paliwa + Capacidade de Combustível @@ -464,6 +469,7 @@ 设定有多少油料可供载具进行加油(-1时关闭,-10为无限油量) 재급유에 사용 할 수 있는 연료량 (-1=비활성, -10=무한) Pojemność paliwa dostępnego do tankowania (-1 wyłącz, -10 jeśli nieskończone) + Quantidade de combustível disponível para abastecer (-1 para desativar, -10 para infinito) Refuel Hose attach coordinates @@ -475,6 +481,7 @@ 加油软管安装位置 재급유기 부착 좌표 Koordynaty przyłączenia węża paliwowego + Coords. do encaixe para Mangueira Model coordinates used to attach refuel hose @@ -486,6 +493,7 @@ 设定加油软管会安装到模型的哪个位置上 재급유기 부착에 쓰이는 모델 좌표 Modelowe koordynaty wykorzystane do przyłączenia węża paliwowego + As coordenadas do modelo usado para conectar a mangueira ao veículo diff --git a/addons/reload/CfgVehicles.hpp b/addons/reload/CfgVehicles.hpp index 7a1d483bd9..fe1e9672e6 100644 --- a/addons/reload/CfgVehicles.hpp +++ b/addons/reload/CfgVehicles.hpp @@ -13,8 +13,8 @@ class CfgVehicles { class GVAR(CheckAmmo) { displayName = CSTRING(checkAmmo); distance = 2.0; - condition = QUOTE([ARR_2(_player, _target)] call FUNC(canCheckAmmo)); - statement = QUOTE([ARR_2(_player, _target)] call FUNC(checkAmmo)); + condition = QUOTE(call FUNC(canCheckAmmo)); + statement = QUOTE(call FUNC(checkAmmo)); exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"}; }; }; @@ -28,8 +28,8 @@ class CfgVehicles { class GVAR(CheckAmmo) { displayName = CSTRING(checkAmmo); distance = 2.0; - condition = QUOTE([ARR_2(_player, _target)] call FUNC(canCheckAmmo)); - statement = QUOTE([ARR_2(_player, _target)] call FUNC(checkAmmo)); + condition = QUOTE(call FUNC(canCheckAmmo)); + statement = QUOTE(call FUNC(checkAmmo)); exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"}; }; }; diff --git a/addons/reload/XEH_postInit.sqf b/addons/reload/XEH_postInit.sqf index eda5c61faa..3e1b95f9bf 100644 --- a/addons/reload/XEH_postInit.sqf +++ b/addons/reload/XEH_postInit.sqf @@ -13,7 +13,7 @@ if (!hasInterface) exitWith {}; if (!isNull (ACE_controlledUAV param [0, objNull])) exitWith {false}; // Statement - [ACE_player] call FUNC(checkAmmo); + [ACE_player, ACE_player] call FUNC(checkAmmo); true }, {false}, [19, [false, true, false]], false] call CBA_fnc_addKeybind; diff --git a/addons/reload/functions/fnc_canCheckAmmo.sqf b/addons/reload/functions/fnc_canCheckAmmo.sqf index a0aa0c5c70..9632d0b4b1 100644 --- a/addons/reload/functions/fnc_canCheckAmmo.sqf +++ b/addons/reload/functions/fnc_canCheckAmmo.sqf @@ -4,19 +4,18 @@ * Check if the player can check the ammo of the target. * * Arguments: - * 0: Unit - * 1: Target + * 0: Target * * Return Value: - * Can link belt + * Can link belt * * Example: - * [player, bob] call ace_reload_fnc_canCheckAmmo + * [cursorObject] call ace_reload_fnc_canCheckAmmo * * Public: No */ -params ["", "_target"]; +params ["_target"]; // Return true for static weapons if they have been fired once, @todo 1.40 this work-around doesn't work anymore if (_target isKindOf "StaticWeapon") exitWith { diff --git a/addons/reload/functions/fnc_checkAmmo.sqf b/addons/reload/functions/fnc_checkAmmo.sqf index 156ca30a32..995e72dc3f 100644 --- a/addons/reload/functions/fnc_checkAmmo.sqf +++ b/addons/reload/functions/fnc_checkAmmo.sqf @@ -4,39 +4,25 @@ * Count the ammo of the currently loaded magazine or count rifle grenades. Play animation and display message. * * Arguments: - * 0: Player - * 1: Target. Optional, if not suplied the player counts his personal or static weapon ammo + * 0: Target. + * 1: Player * * Return Value: * None * * Example: - * [bob, kevin] call ace_reload_fnc_checkAmmo + * [cursorObject, player] call ace_reload_fnc_checkAmmo * * Public: No */ -#define COUNT_BARS 12 +params ["_target", "_player"]; -params ["_unit"]; - -private _target = vehicle _unit; - -if (count _this > 1) then { - _target = _this select 1; -} else { - - // If the unit is on foot, count it's own ammo - if (_unit == _target) exitWith {}; - - // If it's mounted on a movile weapon, count it's own ammo - if !(_target isKindOf "StaticWeapon") then { - _target = _unit; +if (_player == _target) then { + if ((vehicle _target) isKindOf "StaticWeapon") then { + _target = vehicle _target; }; + [_player, "Gear", 1] call EFUNC(common,doGesture); }; -if (_unit == _target) then { - [_unit, "Gear", 1] call EFUNC(common,doGesture); -}; - -[FUNC(displayAmmo), [_target], 1, 0.1] call CBA_fnc_waitAndExecute; +[FUNC(displayAmmo), [_target], 1] call CBA_fnc_waitAndExecute; diff --git a/addons/repair/XEH_postInit.sqf b/addons/repair/XEH_postInit.sqf index 2f0bbe7869..2cbbd8c3e1 100644 --- a/addons/repair/XEH_postInit.sqf +++ b/addons/repair/XEH_postInit.sqf @@ -4,4 +4,17 @@ [QGVAR(setVehicleHitPointDamage), {_this call FUNC(setHitPointDamage)}] call CBA_fnc_addEventHandler; // wheels -[QGVAR(setWheelHitPointDamage), {(_this select 0) setHitPointDamage [_this select 1, _this select 2]}] call CBA_fnc_addEventHandler; +[QGVAR(setWheelHitPointDamage), { + params ["_object", "_hitPoint", "_damage"]; + private _damageDisabled = !isDamageAllowed _object; + + if (_damageDisabled) then { + _object allowDamage true; + }; + + _object setHitPointDamage [_hitPoint, _damage]; + + if (_damageDisabled) then { + _object allowDamage false; + }; +}] call CBA_fnc_addEventHandler; diff --git a/addons/repair/functions/fnc_setDamage.sqf b/addons/repair/functions/fnc_setDamage.sqf index fbae505fae..ba51c22c0d 100644 --- a/addons/repair/functions/fnc_setDamage.sqf +++ b/addons/repair/functions/fnc_setDamage.sqf @@ -26,6 +26,11 @@ if !(local _vehicle) exitWith {}; (getAllHitPointsDamage _vehicle) params [["_allHitPoints", []], ["_allHitPointsSelections", []], ["_allHitPointDamages", []]]; // set damage of the vehicle +private _damageDisabled = !isDamageAllowed _vehicle; +if (_damageDisabled) then { + _vehicle allowDamage true; +}; + _vehicle setDamage _damage; // restore original hitpoint damage values @@ -35,3 +40,7 @@ _vehicle setDamage _damage; // normalize hitpoints [_vehicle] call FUNC(normalizeHitPoints); + +if (_damageDisabled) then { + _vehicle allowDamage false; +}; diff --git a/addons/repair/functions/fnc_setHitPointDamage.sqf b/addons/repair/functions/fnc_setHitPointDamage.sqf index f0313315e9..0e8a805689 100644 --- a/addons/repair/functions/fnc_setHitPointDamage.sqf +++ b/addons/repair/functions/fnc_setHitPointDamage.sqf @@ -62,6 +62,11 @@ if (_hitPointDamageSumOld > 0) then { TRACE_5("structuralDamage",_damageOld,_damageNew,_hitPointDamageRepaired,_hitPointDamageSumOld,_realHitpointCount); // set new structural damage value +private _damageDisabled = !isDamageAllowed _vehicle; +if (_damageDisabled) then { + _vehicle allowDamage true; +}; + _vehicle setDamage [_damageNew, _useEffects]; //Repair the hitpoint in the damages array: @@ -74,3 +79,7 @@ _allHitPointDamages set [_hitPointIndex, _hitPointDamage]; // normalize hitpoints [_vehicle] call FUNC(normalizeHitPoints); + +if (_damageDisabled) then { + _vehicle allowDamage false; +}; diff --git a/addons/repair/stringtable.xml b/addons/repair/stringtable.xml index 467721b8f5..4dd42d4880 100644 --- a/addons/repair/stringtable.xml +++ b/addons/repair/stringtable.xml @@ -1137,6 +1137,8 @@ 只有維修專精兵 Tylko zaawansowani mechanicy 고급 정비공만 + Только продвинутые инженеры + Somente engenheiro avançado Allow Wheel @@ -1463,6 +1465,8 @@ 專精 Zaaw. mechanik 고급 정비공 + Продв. Инженер + Engenheiro Avançado Assign one or multiple units as an engineer @@ -1832,6 +1836,8 @@ 備用履帶 备用履带 Zapasowe Gąsienice + Запасные траки + Esteiras Reservas Number of spare tracks in cargo. @@ -1841,6 +1847,8 @@ 設定載具在貨艙內攜帶的備用履帶數量 设定载具在货舱内携带的备用履带数量。 Liczba zapasowych gąsienic w ładunku. + Количество запасных траков в грузовом отсеке + Número de esteiras reservas na Carga Spare Wheels @@ -1850,6 +1858,8 @@ 備用輪胎 备用轮胎 Zapasowe Koła + Запасные колеса + Pneus Reservas Number of spare wheels in cargo. @@ -1859,22 +1869,30 @@ 設定載具在貨艙內攜帶的備用輪胎數量 设定载具在货舱内携带的备用轮胎数量。 Liczba zapasowych kół w ładunku. + Количество запасных колес в грузовом отсеке + Número de pneus reservas na Carga Auto shut off engine on repair + Motor automatisch ausschalten 修理時にエンジン自動停止 维修时自动关闭发动机。 維修時自動關閉引擎 Motore spento automaticamente durante la riparazione Automatycznie wyłącz silnik podczas napraw + Автоотключение двигателя при ремонте + Desligar motor automaticamente enquanto reparar 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. Automatycznie wyłącz silnik podczas napraw. + Автоматически отключать двигатель при выполнении ремонта + Automaticamente desliga o motor quando iniciar o reparo do veículo. diff --git a/addons/respawn/stringtable.xml b/addons/respawn/stringtable.xml index d87b6efa7c..d6a74651b8 100644 --- a/addons/respawn/stringtable.xml +++ b/addons/respawn/stringtable.xml @@ -3,11 +3,14 @@ Respawn + Wiedereinstieg Riapparizione 重生 重生 リスポン Odrodzenie + Возрождение + Ressurgimento Deploy in 5 seconds... @@ -283,11 +286,14 @@ Body remove timer + Zeit bis Körper entfernt werden Timer rimozione corpo 屍體移除計時器 尸体移除计时器 死体削除タイマー Czas usunięcia ciała + Время удаления трупов + Tempo para remover corpo This module enables you to configure ACE functionality specific to respawns. diff --git a/addons/safemode/XEH_PREP.hpp b/addons/safemode/XEH_PREP.hpp index ab2a755a66..2f23aa02c9 100644 --- a/addons/safemode/XEH_PREP.hpp +++ b/addons/safemode/XEH_PREP.hpp @@ -3,3 +3,4 @@ PREP(lockSafety); PREP(playChangeFiremodeSound); PREP(setSafeModeVisual); PREP(unlockSafety); +PREP(setWeaponSafety); diff --git a/addons/safemode/functions/fnc_lockSafety.sqf b/addons/safemode/functions/fnc_lockSafety.sqf index c3ce5a8b86..44c7208b43 100644 --- a/addons/safemode/functions/fnc_lockSafety.sqf +++ b/addons/safemode/functions/fnc_lockSafety.sqf @@ -17,9 +17,6 @@ * Public: No */ -// don't immediately switch back -if (inputAction "nextWeapon" > 0) exitWith {}; - params ["_unit", "_weapon", "_muzzle"]; private _safedWeapons = _unit getVariable [QGVAR(safedWeapons), []]; diff --git a/addons/safemode/functions/fnc_setWeaponSafety.sqf b/addons/safemode/functions/fnc_setWeaponSafety.sqf new file mode 100644 index 0000000000..4ad0174b20 --- /dev/null +++ b/addons/safemode/functions/fnc_setWeaponSafety.sqf @@ -0,0 +1,36 @@ +#include "script_component.hpp" +/* + * Author: Brostrom.A + * Safe or unsafe the given weapon based on weapon state; locked or unlocked. + * + * Arguments: + * 0: Unit + * 1: Weapon + * 2: State + * + * Return Value: + * None + * + * Example: + * [ACE_player, currentWeapon ACE_player, true] call ace_safemode_fnc_setWeaponSafety + * + * Public: Yes + */ + +params [ + ["_unit", objNull, [objNull]], + ["_weapon", "", [""]], + ["_state", true, [true]] +]; + +if (_weapon == "") exitWith {}; + +private _safedWeapons = _unit getVariable [QGVAR(safedWeapons), []]; + +_weapon = configName (configFile >> "CfgWeapons" >> _weapon); + +private _muzzle = currentMuzzle _unit; + +if !(_state isEqualTo (_weapon in _safedWeapons)) then { + [_unit, _weapon, _muzzle] call FUNC(lockSafety); +}; diff --git a/addons/scopes/CfgWeapons.hpp b/addons/scopes/CfgWeapons.hpp index 86c4820caa..c533cf04c2 100644 --- a/addons/scopes/CfgWeapons.hpp +++ b/addons/scopes/CfgWeapons.hpp @@ -218,11 +218,16 @@ class CfgWeapons { class Rifle_Short_Base_F: Rifle_Base_F {}; class Rifle_Long_Base_F: Rifle_Base_F {}; + class DMR_06_base_F: Rifle_Long_Base_F { + ACE_IronSightBaseAngle = 0.018227; + ACE_RailHeightAboveBore = 3.27488; + }; + class DMR_07_base_F: Rifle_Long_Base_F { ACE_RailHeightAboveBore = 5.07109; ACE_IronSightBaseAngle = -0.00160721; }; - + class arifle_MX_Base_F: Rifle_Base_F { class Single: Mode_SemiAuto {}; class FullAuto: Mode_FullAuto {}; @@ -307,7 +312,7 @@ class CfgWeapons { ACE_RailHeightAboveBore = 5.75468; ACE_IronSightBaseAngle = 0.0863227; }; - + class arifle_MX_F: arifle_MX_Base_F { ACE_RailHeightAboveBore = 2.80201; ACE_IronSightBaseAngle = 0.19502; @@ -375,6 +380,14 @@ class CfgWeapons { ACE_IronSightBaseAngle = -0.1532926; }; + class arifle_MSBS65_base_F: Rifle_Base_F { + ACE_RailHeightAboveBore = 5.2; + ACE_IronSightBaseAngle = -0.028648; + }; + class arifle_MSBS65_Mark_base_F: arifle_MSBS65_base_F { + ACE_IronSightBaseAngle = -0.045837; + }; + class EBR_base_F: Rifle_Long_Base_F {}; class LRR_base_F: Rifle_Long_Base_F {}; class GM6_base_F: Rifle_Long_Base_F {}; @@ -383,7 +396,6 @@ class CfgWeapons { class DMR_03_base_F: Rifle_Long_Base_F {}; class DMR_04_base_F: Rifle_Long_Base_F {}; class DMR_05_base_F: Rifle_Long_Base_F {}; - class DMR_06_base_F: Rifle_Long_Base_F {}; class srifle_EBR_F: EBR_base_F { ACE_RailHeightAboveBore = 1.98812; @@ -417,10 +429,6 @@ class CfgWeapons { ACE_RailHeightAboveBore = 3.91334; ACE_IronSightBaseAngle = 0.0123425; }; - class srifle_DMR_06_camo_F: DMR_06_base_F { - ACE_RailHeightAboveBore = 3.27488; - ACE_IronSightBaseAngle = 0.018227; - }; class MMG_01_base_F; class MMG_02_base_F; diff --git a/addons/scopes/stringtable.xml b/addons/scopes/stringtable.xml index 2c6030801f..24ec614fc8 100644 --- a/addons/scopes/stringtable.xml +++ b/addons/scopes/stringtable.xml @@ -11,6 +11,8 @@ Mirini 瞄准镜 瞄準鏡 + Прицелы + Mira Telescópica Enable ACE Scope adjustment @@ -22,6 +24,8 @@ Abilita Regolazione mirino ACE 开启ACE瞄准镜归零调节 開啟ACE瞄準鏡歸零調節 + Включить настройку прицелов ACE + Permitir ajustes de Mira do ACE Enable adjustment turrets on high powered scopes @@ -33,6 +37,8 @@ Abilita la regolazione delle torrette nei mirini a lunga gittata 开启高倍率瞄准镜归零调节 開啟高倍率瞄準鏡歸零調節 + Включает регулировочные барабанчики ввода поправок на прицелах с высокой кратностью + Permite que as Miras Telescópicas sejam ajustadas com ACE Force adjustment turrets @@ -44,9 +50,11 @@ Forza la regolazione delle torrette 强制使用归零调节 強制使用歸零調節 + Включить регулировку ненастроенных прицелов + Força ajustes ACE para Miras - Force usage of adjustmet turrets on high powered scopes + Force usage of adjustment turrets on high powered scopes Erzwinge Absehenverstellungen für Waffen mit Zielfernrohren 高倍率スコープで調整の使用を強制させます 고성능 조준경의 조절 나사 사용을 강제합니다 @@ -55,6 +63,8 @@ Forza l'uso della regolazione nei mirini a lunga gittata 强制为高倍率瞄准镜开启归零调节 強制為高倍率瞄準鏡開啟歸零調節 + Принудительно использовать барабанчики ввода поправок для ненастроенных прицелов с высокой кратностью + Força o uso dos controles de ajuste de Mira do ACE em Miras Telescópicas Correct zeroing @@ -66,6 +76,8 @@ Correggi azzeramento 修正归零 修正歸零 + Корректировать пристрелку + Corrigir Zeramento Corrects the zeroing of all small arms sights @@ -77,6 +89,8 @@ Corregge l'azzeramento di tutti i mirini di bassa portata 为所有小口径武器修正归零 為所有小口徑武器修正歸零 + Позволяет корректировать пристрелку для всех прицелов стрелкового оружия + Corrige o Zeramento de todas as miras de armas pequenas. (Zeroing) Overwrite zero distance @@ -88,6 +102,8 @@ Sovrascrivi la distanza zero 覆写归零距离 覆寫歸零距離 + Перезаписать дальность пристрелки + Sobrepor distância zero Uses the 'defaultZeroRange' setting to overwrite the zero range of high power scopes @@ -99,6 +115,8 @@ Usa le impostazioni di "defaultZeroRange" (Portata Zero Predefinita) per sovrascrivere la portata zero dei mirini a lunga gittata 使用'defaultZeroRange'来为高倍率瞄准镜覆写预设归零距离 使用'defaultZeroRange'來為高倍率瞄準鏡覆寫預設歸零距離 + Использует настройку 'defaultZeroRange' для перенастройки дальности пристрелки прицелов с высокой кратностью + Utiliza a configuração 'Distância Zero Padrão' para sobrepor a distância zero de Miras Telescópicas Default zero distance @@ -110,6 +128,8 @@ Distanza zero predefinita 预设归零距离 預設歸零距離 + Дальность пристрелки по умолчанию + Distância Zero Padrão High powered scopes will be zeroed at this distance @@ -121,6 +141,8 @@ I mirini a lunga gittata verranno azzerrati a questa distanza 高倍率瞄准镜将归零在这个距离上 高倍率瞄準鏡將歸零在這個距離上 + Дальность, на которую будут пристреляны прицелы с высокой кратностью + Miras Telescópicas serão zeradas nessa distância Reference temperature @@ -132,6 +154,8 @@ Temperatura di riferimento 参考温度 參考溫度 + Референсная температура + Temperatura de Referência Temperature at which the scope was zeroed @@ -143,6 +167,8 @@ Temperatura a cui è stato azzerato il mirino 武器参考多少温度来进行归零. 武器參考多少溫度來進行歸零. + Температура, при которой выполнена пристрелка прицела + Temperatura na qual a mira foi zerada. Reference barometric pressure @@ -154,6 +180,8 @@ Pressione barometrica di riferimento 参考大气压力 參考大氣壓力 + Референсное давление + Pressão Barométrica de Referência Barometric pressure at which the scope was zeroed @@ -165,6 +193,8 @@ Pressione barometrica a cui è stato azzerato il mirino 武器参考多少大气压力来进行归零。 武器參考多少大氣壓力來進行歸零。 + Давление, при котором выполнена пристрелка прицела + Pressão Barométrica de quando a mira foi zerada. Reference humidity @@ -176,6 +206,8 @@ Umidità di riferimento 参考湿度 參考濕度 + Референсная влажность + Humidade de Referência Humidity at which the scope was zeroed @@ -187,6 +219,8 @@ Umidità a cui è stato azzerato il mirino 武器参考多少湿度来进行归零。 武器參考多少濕度來進行歸零。 + Влажность, при которой выполнена пристрелка прицела + Humidade na qual a mira foi zerada. Deduce pressure from altitude @@ -198,6 +232,8 @@ Ricava la pressione dall'altitudine 高度影响大气压力 高度影響大氣壓力 + Просчитать давление из высоты + Deduzir pressão pela altitude Deduce the barometric pressure from the terrain altitude @@ -209,6 +245,8 @@ Ricava la pressione barometrica dall'altitudine del terreno 在不同高度上会有不同的大气压力 在不同高度上會有不同的大氣壓力 + Давление определяется по высоте + Deduz a pressão barométrica pela altitude do terreno. Use legacy UI @@ -219,6 +257,8 @@ 昔の UI を使用 기존 UI 사용 Wykorzystaj legacy UI + Использовать устаревший интерфейс + Usar Interface Antiga Displays elevation and windage with signed numbers @@ -229,6 +269,8 @@ 印付きの数字で仰角と横風を表示 기존의 부호가 있는 숫자로 표고와 폭을 표시합니다. Wyświetla elewację i tarcie powietrza poprzez podpisane liczby + Отображает горизонтальные и вертикальные поправки с подписанными числами + Exibir elevação e vento com número sinalizados. Simplified zeroing @@ -239,6 +281,8 @@ 簡單歸零 简单归零 Uproszczone zerowanie + Упрощенная пристрелка + Zeramento Simplificado Replicates the vanilla zeroing system for riflescopes. @@ -249,12 +293,14 @@ 使用原版的歸零系統來取代ACE複雜的歸零模擬。 使用原版的归零系统来取代ACE复杂的归零模拟。 Replikuje system zerowania, dla celowników karabinowych, z domyślnej gry. + Использует ванильную систему прицеливания для прицелов + Imita o sistema de zeramento vanilla para miras de rifle. Minor adjustment up Kleine Korrektur hoch Zerowanie powoli w górę - Малая корректировка ВВЕРХ + Малая поправка ВВЕРХ Ajuste menor arriba Regola leggermente alzata in alto Hausse + @@ -270,7 +316,7 @@ Minor adjustment down Kleine Korrektur runter Zerowanie powoli w dół - Малая корректировка ВНИЗ + Малая поправка ВНИЗ Ajuste menor abajo Regola leggermente alzata in basso Hausse - @@ -286,7 +332,7 @@ Minor adjustment right Kleine Korrektur rechts Zerowanie powoli w prawo - Малая корректировка ВПРАВО + Малая поправка ВПРАВО Ajuste menor derecha Regola leggermente il tiro a destra Dérive + @@ -302,7 +348,7 @@ Minor adjustment left Kleine Korrektur links Zerowanie powoli w lewo - Малая корректировка ВЛЕВО + Малая поправка ВЛЕВО Ajuste menor izquierda Regola leggermete il tiro a sinistra Dérive - @@ -318,7 +364,7 @@ Major adjustment up Große Korrektur hoch Zerowanie w górę - Большая корректировка ВВЕРХ + Большая поправка ВВЕРХ Ajuste mayor arriba Regola l'alzata in alto Hausse +++ @@ -334,7 +380,7 @@ Major adjustment down Große Korrektur runter Zerowanie w dół - Большая корректировка ВНИЗ + Большая поправка ВНИЗ Ajuste mayor abajo Regola l'alzata in basso Hausse - - - @@ -350,7 +396,7 @@ Major adjustment right Große Korrektur rechts Zerowanie w prawo - Большая корректировка ВПРАВО + Большая поправка ВПРАВО Ajuste mayor derecha Regola il tiro a destra Dérive +++ @@ -366,7 +412,7 @@ Major adjustment left Große Korrektur links Zerowanie w lewo - Большая корректировка ВЛЕВО + Большая поправка ВЛЕВО Ajuste mayor izquierda Regola il tiro a sinistra Dérive - - - @@ -382,7 +428,7 @@ Set zero adjustment Nullung durchführen Ustaw wyzerowanie - Сбросить корректировку + Установить дальность пристрелки Establecer ajuste a cero Imposta i valori dell'azzeramento RAZ corrections @@ -403,6 +449,8 @@ 重設歸零 重设归零 Zresetuj wyzerowanie + Сбросить дальность пристрелки + Resetar Ajuste Zero This module adds windage and elevation adjustment turrets on high power rifle scopes. @@ -414,6 +462,8 @@ Questo modulo aggiunge lo spostamento dell'aria e la regolazione dell'elevazione delle torrette in mirini a lunga gittata 此模块可为高倍率瞄准镜新增归零风偏,距离用的调整纽。 此模塊可為高倍率瞄準鏡新增歸零風偏,距離用的調整紐。 + Этот модуль добавляет барабанчики ввода горизонтальных и вертикальных поправок для прицелов с высокой кратностью + Esse módulo implementa vento e elevação para os ajustes de miras telescópicas. %1D @@ -425,6 +475,8 @@ %1D %1D %1D + %1D + %1D %1L @@ -436,6 +488,8 @@ %1L %1L %1L + %1L + %1L %1R @@ -447,20 +501,28 @@ %1R %1R %1R + %1R + %1R Horizontal limits + Horizontale Grenzen 水平限制 水平制限 Limite orrizontale Limit poziomy + Лимит по горизонтали + Limite Horizontal Vertical limits + Vertikale Grenzen 垂直限制 垂直制限 Limite verticale Limit pionowy + Лимит по вертикали + Limite Vertical diff --git a/addons/slideshow/functions/fnc_createSlideshow.sqf b/addons/slideshow/functions/fnc_createSlideshow.sqf index 965a823941..290fad89b4 100644 --- a/addons/slideshow/functions/fnc_createSlideshow.sqf +++ b/addons/slideshow/functions/fnc_createSlideshow.sqf @@ -64,6 +64,11 @@ if !(["ace_interact_menu"] call EFUNC(common,isModLoaded)) then { // Add interactions if automatic transitions are disabled, else setup automatic transitions if (_duration == 0) then { + + // Reverse the arrays so that the interactions will be added in the right order + reverse _images; + reverse _names; + { if (_setName == "") then { _setName = localize LSTRING(Interaction); diff --git a/addons/slideshow/functions/fnc_moduleInit.sqf b/addons/slideshow/functions/fnc_moduleInit.sqf index b3cbf8bf43..a8cf27ceec 100644 --- a/addons/slideshow/functions/fnc_moduleInit.sqf +++ b/addons/slideshow/functions/fnc_moduleInit.sqf @@ -42,4 +42,4 @@ private _duration = _logic getVariable ["Duration", 0]; // Prepare with actions [_objects, _controllers, _images, _names, _duration, _setName] call FUNC(createSlideshow); -INFO_1("Slideshow Module Initialized on %1 Objects", count _objects); +INFO_1("Slideshow Module Initialized on %1 Objects",(count _objects)); diff --git a/addons/slideshow/stringtable.xml b/addons/slideshow/stringtable.xml index 7f37e06b01..3cc62d4ee7 100644 --- a/addons/slideshow/stringtable.xml +++ b/addons/slideshow/stringtable.xml @@ -161,7 +161,7 @@ Set Name - Setze Namen + Name der Diavorführung Ustaw nazwę 名前設定 Définir le nom @@ -169,6 +169,8 @@ 設定名稱 设定名称 이름 설정 + Установить имя + Definir Nome Name that will be used for main interaction entry (to distinguish multiple slideshows). Default: "Slides" @@ -180,6 +182,8 @@ 設定該幻燈片的標題名稱 (用來區分多個不同標題的幻燈片) 預設名稱: "幻燈片" 设定该幻灯片的标题名称 (用来区分多个不同标题的幻灯片) 预设名称: "幻灯片" 상위 상호작용 이름 (여러개의 슬라이드 쇼를 구분하기 위해 사용됨) 기본: "Slides" + Имя, которое будет использоваться для основных взаимодействий (для различения нескольких слайдов). По умолчанию: «Slides» + Nome que será usado para a entrada principal de interação (para separar vários slideshows). Padrão: "Slides" Slide Duration diff --git a/addons/spectator/ACE_Settings.hpp b/addons/spectator/ACE_Settings.hpp index ef74580428..3bd0f0bc50 100644 --- a/addons/spectator/ACE_Settings.hpp +++ b/addons/spectator/ACE_Settings.hpp @@ -1,25 +1,11 @@ class ACE_Settings { class GVAR(enableAI) { - category = CSTRING(Module_DisplayName); - displayName = CSTRING(ai_DisplayName); - description = CSTRING(ai_Description); - typeName = "BOOL"; - value = 0; + movedToSQF = 1; }; class GVAR(restrictModes) { - category = CSTRING(Module_DisplayName); - displayName = CSTRING(modes_DisplayName); - description = CSTRING(modes_Description); - typeName = "SCALAR"; - value = 0; - values[] = {CSTRING(modes_all), CSTRING(modes_unit), "$STR_A3_Spectator_free_camera_tooltip", "$STR_A3_Spectator_1pp_camera_tooltip", "$STR_A3_Spectator_3pp_camera_tooltip"}; + movedToSQF = 1; }; class GVAR(restrictVisions) { - category = CSTRING(Module_DisplayName); - displayName = CSTRING(visions_DisplayName); - description = CSTRING(visions_Description); - typeName = "SCALAR"; - value = 0; - values[] = {CSTRING(modes_all), CSTRING(visions_nv), CSTRING(visions_ti), "$STR_Special_None"}; + movedToSQF = 1; }; }; diff --git a/addons/spectator/XEH_preInit.sqf b/addons/spectator/XEH_preInit.sqf index 8220b21520..1e3d019177 100644 --- a/addons/spectator/XEH_preInit.sqf +++ b/addons/spectator/XEH_preInit.sqf @@ -6,6 +6,8 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.sqf" + // Used by public functions GVAR(availableModes) = [MODE_FREE, MODE_FPS, MODE_FOLLOW]; GVAR(availableSides) = [west,east,resistance,civilian]; diff --git a/addons/spectator/functions/fnc_ui_handleMouseZChanged.sqf b/addons/spectator/functions/fnc_ui_handleMouseZChanged.sqf index 8b109d430c..b402d9830e 100644 --- a/addons/spectator/functions/fnc_ui_handleMouseZChanged.sqf +++ b/addons/spectator/functions/fnc_ui_handleMouseZChanged.sqf @@ -15,12 +15,11 @@ * * Public: No */ -#define FOLLOW_CAMERA_MAX_DISTANCE 5 if (GVAR(camMode) == MODE_FOLLOW) then { if ((_this select 1) > 0) then { GVAR(camDistance) = (GVAR(camDistance) - 1) max 0; } else { - GVAR(camDistance) = (GVAR(camDistance) + 1) min FOLLOW_CAMERA_MAX_DISTANCE; + GVAR(camDistance) = (GVAR(camDistance) + 1) min GVAR(maxFollowDistance); }; }; diff --git a/addons/spectator/initSettings.sqf b/addons/spectator/initSettings.sqf new file mode 100644 index 0000000000..c970fe77c7 --- /dev/null +++ b/addons/spectator/initSettings.sqf @@ -0,0 +1,39 @@ +[ + QGVAR(enableAI), + "CHECKBOX", + [LSTRING(ai_DisplayName), LSTRING(ai_Description)], + LSTRING(Settings_DisplayName), + false, + true +] call CBA_settings_fnc_init; + +[ + QGVAR(restrictModes), + "LIST", + [LSTRING(modes_DisplayName), LSTRING(modes_Description)], + LSTRING(Settings_DisplayName), + [[0, 1, 2, 3, 4], [LSTRING(modes_all), LSTRING(modes_unit), "STR_A3_Spectator_free_camera_tooltip", "STR_A3_Spectator_1pp_camera_tooltip", "STR_A3_Spectator_3pp_camera_tooltip"], 0], + true, + {}, + true +] call CBA_settings_fnc_init; + +[ + QGVAR(restrictVisions), + "LIST", + [LSTRING(visions_DisplayName), LSTRING(visions_Description)], + LSTRING(Settings_DisplayName), + [[0, 1, 2, 3], [LSTRING(modes_all), LSTRING(visions_nv), LSTRING(visions_ti), "STR_Special_None"], 0], + true, + {}, + true +] call CBA_settings_fnc_init; + +[ + QGVAR(maxFollowDistance), + "SLIDER", + [LSTRING(MaxFollowDistance_DisplayName), LSTRING(MaxFollowDistance_Description)], + LSTRING(Settings_DisplayName), + [5, 25, 5, 1], + false +] call CBA_settings_fnc_init; diff --git a/addons/spectator/stringtable.xml b/addons/spectator/stringtable.xml index 634fd675cf..f236e78a10 100644 --- a/addons/spectator/stringtable.xml +++ b/addons/spectator/stringtable.xml @@ -11,6 +11,8 @@ 관전자 Spectateur Obserwator + Зритель + Espectador ACE Spectator @@ -22,6 +24,8 @@ ACE 旁觀者 Obserwator ACE ACE 관전자 + ACE Зритель + ACE Espectador Configure how the spectator system will operate by default. @@ -48,6 +52,8 @@ AI 활성 IA Activée SI Aktywowane + Разрешить для ИИ + IA Ativado Make AI viewable in spectator @@ -59,6 +65,8 @@ 관전자가 AI를 관전 할 수 있습니다. Rends les IA visibles en spectateur Spraw, aby SI było widoczne jako obserwator + Сделать ИИ видимыми в режиме зрителя + Permite que IA seja visivel no espectador Camera modes @@ -180,6 +188,18 @@ 热成像 熱成像 + + Max Follow Distance + Макс. дистанция следования + 最大追随距離 + Distância Máxima de Acompanhamento + + + Maximum distance the follow camera can be from the target + Максимальная дистанция от камеры слежения до цели + カメラが目標へ追随できる最大距離を決定できます。 + A distância máxima que a câmera de acompanhamento pode estar do alvo. + Engineer @@ -267,6 +287,8 @@ 아이콘 Icônes Ikony + Иконки + Ícones Projectiles @@ -278,6 +300,8 @@ 발사체 Projectiles Pociski + Осколки + Projéteis Next Unit @@ -319,6 +343,8 @@ 보기 모드 Mode de vision Tryb Wizji + Режим видения + Modo de Visão Slow Speed @@ -330,6 +356,8 @@ 느린 속도 Vitesse lente Wolna Prędkość + Замедление + Velocidade Lenta diff --git a/addons/spottingscope/CfgOpticsEffect.hpp b/addons/spottingscope/CfgOpticsEffect.hpp new file mode 100644 index 0000000000..2b9542ba9c --- /dev/null +++ b/addons/spottingscope/CfgOpticsEffect.hpp @@ -0,0 +1,7 @@ +class CfgOpticsEffect { + class GVAR(OpticsRadBlur1) { + type = "radialblur"; + params[] = {0.01,0.01,0.18,0.36}; + priority = 950; + }; +}; diff --git a/addons/spottingscope/CfgVehicles.hpp b/addons/spottingscope/CfgVehicles.hpp index d961f0d36b..660a3d6749 100644 --- a/addons/spottingscope/CfgVehicles.hpp +++ b/addons/spottingscope/CfgVehicles.hpp @@ -27,23 +27,16 @@ class CfgVehicles { class LandVehicle; class StaticWeapon: LandVehicle { - class Turrets; + class Turrets { + class MainTurret; + }; + class ACE_Actions { class ACE_MainActions; }; }; - class StaticATWeapon: StaticWeapon { - class Turrets: Turrets { - class MainTurret; - }; - - class ACE_Actions: ACE_Actions { - class ACE_MainActions: ACE_MainActions {}; - }; - }; - - class ACE_SpottingScopeObject: StaticATWeapon { + class ACE_SpottingScopeObject: StaticWeapon { EGVAR(dragging,canDrag) = 1; EGVAR(dragging,dragPosition)[] = {0,1,0}; EGVAR(dragging,dragDirection) = 0; @@ -68,6 +61,8 @@ class CfgVehicles { class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers_base {}; }; + CBA_ScriptedOpticClass = "ACE_SpottingScopeOptic"; + author = ECSTRING(common,ACETeam); scope = 1; side = 1; @@ -84,6 +79,7 @@ class CfgVehicles { accuracy = 0.12; cost = 10000; icon = "\A3\Static_F_Gamma\data\UI\map_StaticTurret_AT_CA.paa"; + attenuationEffectType = ""; class SpeechVariants { class Default { @@ -123,15 +119,15 @@ class CfgVehicles { initAngleY = 0; minAngleY = -100; maxAngleY = 100; - minFov = 0.0025; - maxFov = 0.05; - initFov= 0.05; + minFov = "0.25/35"; // real one is 15x-45x, but max mag in game is 37x + maxFov = "0.25/5"; + initFov= "0.25/5"; }; weapons[] = {}; magazines[] = {}; gunnerOpticsColor[] = {1,1,1,1}; - gunnerOpticsModel = "\A3\Weapons_F\empty"; + gunnerOpticsModel = "\A3\Weapons_F\empty.p3d"; gunnerOpticsEffect[] = {"OpticsCHAbera1","OpticsBlur2"}; gunnerOutOpticsShowCursor = 0; gunnerOpticsShowCursor = 0; @@ -140,7 +136,7 @@ class CfgVehicles { gunnerGetOutAction = "PlayerProne"; gunnerForceOptics = 0; ejectDeadGunner = 0; - turretInfoType = QGVAR(RscUnitInfo); + turretInfoType = "CBA_ScriptedOptic_zooming"; opticsDisablePeripherialVision = 1; }; }; diff --git a/addons/spottingscope/CfgWeapons.hpp b/addons/spottingscope/CfgWeapons.hpp index 9548b30aee..2949920602 100644 --- a/addons/spottingscope/CfgWeapons.hpp +++ b/addons/spottingscope/CfgWeapons.hpp @@ -1,4 +1,3 @@ - class CfgWeapons { class ACE_ItemCore; class CBA_MiscItem_ItemInfo; @@ -15,4 +14,31 @@ class CfgWeapons { mass = 40; }; }; + + class ItemCore; + class ACE_SpottingScopeOptic: ItemCore { + scope = 1; + + class CBA_ScriptedOptic { + minMagnificationReticleScale[] = {5,1}; + maxMagnificationReticleScale[] = {25,5}; + + reticleDetailTextures[] = { + // start at > this magnification, reticleTexture, reticleTextureSize, reticleTextureNight (optional) + {0, PATHTOF(data\ace_spottingscope_reticle_b1_ca.paa), 1, PATHTOF(data\ace_spottingscope_reticle_b1_ca.paa)}, + {9, PATHTOF(data\ace_spottingscope_reticle_b2_ca.paa), 1/2, PATHTOF(data\ace_spottingscope_reticle_b2_ca.paa)}, + {14, PATHTOF(data\ace_spottingscope_reticle_b3_ca.paa), 1/3, PATHTOF(data\ace_spottingscope_reticle_b3_ca.paa)}, + {19, PATHTOF(data\ace_spottingscope_reticle_b4_ca.paa), 1/4, PATHTOF(data\ace_spottingscope_reticle_b4_ca.paa)}, + {24, PATHTOF(data\ace_spottingscope_reticle_b5_ca.paa), 1/5, PATHTOF(data\ace_spottingscope_reticle_b5_ca.paa)} + }; + fadeReticleInterval[] = {10.5,9.5}; + + bodyTexture = QPATHTOF(data\ace_spottingscope_body_co.paa); + //bodyTextureNight = QPATHTOF(data\ace_spottingscope_body_co.paa); + bodyTextureSize = 1.5; + reticleSafezoneSize = 1; + hidePeripheralVision = 1; + opticsPPEffects[] = {QGVAR(OpticsRadBlur1)}; + }; + }; }; diff --git a/addons/spottingscope/RscInGameUI.hpp b/addons/spottingscope/RscInGameUI.hpp deleted file mode 100644 index bf4f086dd7..0000000000 --- a/addons/spottingscope/RscInGameUI.hpp +++ /dev/null @@ -1,56 +0,0 @@ - -class RscOpticsValue; -class RscMapControl; -class RscText; -class RscPicture; - -class RscInGameUI { - class RscUnitInfo; - class GVAR(RscUnitInfo): RscUnitInfo { - onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscUnitInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); {((_this select 0) displayCtrl _x) ctrlShow false} forEach [ARR_4(IDC_RETICLE,IDC_BODY,IDC_BLACK_LEFT,IDC_BLACK_RIGHT)]); - controls[] = {"CA_FOVMode","ScriptedReticleHelper","trippleHeadLeft","trippleHeadRight","Reticle","Body"}; // don't change this order - - class CA_FOVMode: RscOpticsValue { // idea by Taosenai. Apparently this can be used via isNil check to determine wheter the scope or the kolimator is used - idc = 154; - w = 0; - h = 0; - }; - - class ScriptedReticleHelper: RscMapControl { - onDraw = QUOTE(ctrlParent (_this select 0) call FUNC(animateReticle)); - idc = -1; - w = 0; - h = 0; - }; - - class Reticle: RscPicture { - idc = IDC_RETICLE; - text = QPATHTOF(rsc\spotting_scope_reticle_co.paa); - x = POS_X; - y = POS_Y; - w = POS_W; - h = POS_H; - }; - - class Body: Reticle { - idc = IDC_BODY; - text = QPATHTOF(rsc\spotting_scope_body_co.paa); - }; - - //These are just black side panels to cover the areas that the optics p3d doesn't cover - //It will ONLY effect tripple head users as (safezoneX == safeZoneXAbs) for everyone else - class trippleHeadLeft: RscText { - idc = IDC_BLACK_LEFT; - x = "safeZoneXAbs"; - Y = "safezoneY"; - w = QUOTE(POS_X_BASE(SIZEX) - safeZoneXAbs); - h = "safeZoneH"; - colorBackground[] = {0,0,0,1}; - }; - - class trippleHeadRight: trippleHeadLeft { - idc = IDC_BLACK_RIGHT; - x = QUOTE(safeZoneXAbs + safeZoneWAbs - (POS_X_BASE(SIZEX) - safeZoneXABS)); - }; - }; -}; diff --git a/addons/spottingscope/XEH_PREP.hpp b/addons/spottingscope/XEH_PREP.hpp index 9839872360..75bc471556 100644 --- a/addons/spottingscope/XEH_PREP.hpp +++ b/addons/spottingscope/XEH_PREP.hpp @@ -1,4 +1,2 @@ - PREP(pickup); PREP(place); -PREP(animateReticle); diff --git a/addons/spottingscope/XEH_preInit.sqf b/addons/spottingscope/XEH_preInit.sqf index e80d5e4ef9..13d220d959 100644 --- a/addons/spottingscope/XEH_preInit.sqf +++ b/addons/spottingscope/XEH_preInit.sqf @@ -16,4 +16,12 @@ PREP_RECOMPILE_END; _tube addTorque (vectorNormalized [1 - random 2, 1 - random 2, 1 - random 2] vectorMultiply 4); }] call CBA_fnc_addClassEventHandler; +["ACE_SpottingScopeObject", "GetOut", { + params ["_vehicle", "", "_unit"]; + + if (local _unit) then { + _unit setDir getDir _vehicle; + }; +}] call CBA_fnc_addClassEventHandler; + ADDON = true; diff --git a/addons/spottingscope/config.cpp b/addons/spottingscope/config.cpp index 5e8576eb59..c7a0b8a8c9 100644 --- a/addons/spottingscope/config.cpp +++ b/addons/spottingscope/config.cpp @@ -18,5 +18,8 @@ class CfgPatches { #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" #include "CfgMoves.hpp" +#include "CfgOpticsEffect.hpp" -#include "RscInGameUI.hpp" +class CBA_PIPItems { + GVAR(enable) = "-"; +}; diff --git a/addons/spottingscope/rsc/spotting_scope_body_co.paa b/addons/spottingscope/data/ace_spottingscope_body_co.paa similarity index 100% rename from addons/spottingscope/rsc/spotting_scope_body_co.paa rename to addons/spottingscope/data/ace_spottingscope_body_co.paa diff --git a/addons/spottingscope/data/ace_spottingscope_reticle_a1_ca.paa b/addons/spottingscope/data/ace_spottingscope_reticle_a1_ca.paa new file mode 100644 index 0000000000..01fb142cf1 Binary files /dev/null and b/addons/spottingscope/data/ace_spottingscope_reticle_a1_ca.paa differ diff --git a/addons/spottingscope/data/ace_spottingscope_reticle_a1_night_ca.paa b/addons/spottingscope/data/ace_spottingscope_reticle_a1_night_ca.paa new file mode 100644 index 0000000000..332c5e9630 Binary files /dev/null and b/addons/spottingscope/data/ace_spottingscope_reticle_a1_night_ca.paa differ diff --git a/addons/spottingscope/data/ace_spottingscope_reticle_a2_ca.paa b/addons/spottingscope/data/ace_spottingscope_reticle_a2_ca.paa new file mode 100644 index 0000000000..5c2c5cedf7 Binary files /dev/null and b/addons/spottingscope/data/ace_spottingscope_reticle_a2_ca.paa differ diff --git a/addons/spottingscope/data/ace_spottingscope_reticle_a2_night_ca.paa b/addons/spottingscope/data/ace_spottingscope_reticle_a2_night_ca.paa new file mode 100644 index 0000000000..d95f44fad4 Binary files /dev/null and b/addons/spottingscope/data/ace_spottingscope_reticle_a2_night_ca.paa differ diff --git a/addons/spottingscope/data/ace_spottingscope_reticle_a3_ca.paa b/addons/spottingscope/data/ace_spottingscope_reticle_a3_ca.paa new file mode 100644 index 0000000000..815d283700 Binary files /dev/null and b/addons/spottingscope/data/ace_spottingscope_reticle_a3_ca.paa differ diff --git a/addons/spottingscope/data/ace_spottingscope_reticle_a3_night_ca.paa b/addons/spottingscope/data/ace_spottingscope_reticle_a3_night_ca.paa new file mode 100644 index 0000000000..e018ceb7e2 Binary files /dev/null and b/addons/spottingscope/data/ace_spottingscope_reticle_a3_night_ca.paa differ diff --git a/addons/spottingscope/data/ace_spottingscope_reticle_a4_ca.paa b/addons/spottingscope/data/ace_spottingscope_reticle_a4_ca.paa new file mode 100644 index 0000000000..5a0ce5dd4a Binary files /dev/null and b/addons/spottingscope/data/ace_spottingscope_reticle_a4_ca.paa differ diff --git a/addons/spottingscope/data/ace_spottingscope_reticle_a4_night_ca.paa b/addons/spottingscope/data/ace_spottingscope_reticle_a4_night_ca.paa new file mode 100644 index 0000000000..129571c875 Binary files /dev/null and b/addons/spottingscope/data/ace_spottingscope_reticle_a4_night_ca.paa differ diff --git a/addons/spottingscope/data/ace_spottingscope_reticle_a5_ca.paa b/addons/spottingscope/data/ace_spottingscope_reticle_a5_ca.paa new file mode 100644 index 0000000000..990a1299d4 Binary files /dev/null and b/addons/spottingscope/data/ace_spottingscope_reticle_a5_ca.paa differ diff --git a/addons/spottingscope/data/ace_spottingscope_reticle_a5_night_ca.paa b/addons/spottingscope/data/ace_spottingscope_reticle_a5_night_ca.paa new file mode 100644 index 0000000000..614946f358 Binary files /dev/null and b/addons/spottingscope/data/ace_spottingscope_reticle_a5_night_ca.paa differ diff --git a/addons/spottingscope/data/ace_spottingscope_reticle_b1_ca.paa b/addons/spottingscope/data/ace_spottingscope_reticle_b1_ca.paa new file mode 100644 index 0000000000..dc938d7376 Binary files /dev/null and b/addons/spottingscope/data/ace_spottingscope_reticle_b1_ca.paa differ diff --git a/addons/spottingscope/data/ace_spottingscope_reticle_b2_ca.paa b/addons/spottingscope/data/ace_spottingscope_reticle_b2_ca.paa new file mode 100644 index 0000000000..dee69b091f Binary files /dev/null and b/addons/spottingscope/data/ace_spottingscope_reticle_b2_ca.paa differ diff --git a/addons/spottingscope/data/ace_spottingscope_reticle_b3_ca.paa b/addons/spottingscope/data/ace_spottingscope_reticle_b3_ca.paa new file mode 100644 index 0000000000..a7eec0cf63 Binary files /dev/null and b/addons/spottingscope/data/ace_spottingscope_reticle_b3_ca.paa differ diff --git a/addons/spottingscope/data/ace_spottingscope_reticle_b4_ca.paa b/addons/spottingscope/data/ace_spottingscope_reticle_b4_ca.paa new file mode 100644 index 0000000000..b0978523f8 Binary files /dev/null and b/addons/spottingscope/data/ace_spottingscope_reticle_b4_ca.paa differ diff --git a/addons/spottingscope/data/ace_spottingscope_reticle_b5_ca.paa b/addons/spottingscope/data/ace_spottingscope_reticle_b5_ca.paa new file mode 100644 index 0000000000..40837aa44c Binary files /dev/null and b/addons/spottingscope/data/ace_spottingscope_reticle_b5_ca.paa differ diff --git a/addons/spottingscope/functions/fnc_animateReticle.sqf b/addons/spottingscope/functions/fnc_animateReticle.sqf deleted file mode 100644 index adca733814..0000000000 --- a/addons/spottingscope/functions/fnc_animateReticle.sqf +++ /dev/null @@ -1,47 +0,0 @@ -#include "script_component.hpp" -/* - * Author: commy2 - * Animate scripted reticle of spotting scope. - * - * Arguments: - * 0: Reticles RSC info display - * - * Return Value: - * None - * - * Example: - * [DISPLAY] call ace_spottingscope_fnc_animateReticle - * - * Public: No - */ - -disableSerialization; - -params ["_display"]; -uinamespace setVariable [QGVAR(dlgSpottingScope), _display]; - -private _ctrlReticle = _display displayCtrl IDC_RETICLE; -private _ctrlBody = _display displayCtrl IDC_BODY; -private _ctrlBlackLeft = _display displayCtrl IDC_BLACK_LEFT; -private _ctrlBlackRight = _display displayCtrl IDC_BLACK_RIGHT; - -// check if optics are used -// hide all controls otherwise -private _isUsingOptic = ctrlShown (_display displayCtrl 154); - -_ctrlReticle ctrlShow _isUsingOptic; -_ctrlBody ctrlShow _isUsingOptic; -_ctrlBlackLeft ctrlShow _isUsingOptic; -_ctrlBlackRight ctrlShow _isUsingOptic; - -// animate reticle -private _zoom = ([] call EFUNC(common,getZoom)) * MAGIC_SCOPE_NUMBER; - -_ctrlReticle ctrlSetPosition [ - POS_X_BASE(_zoom), - POS_Y_BASE(_zoom), - POS_W_BASE(_zoom), - POS_H_BASE(_zoom) -]; - -_ctrlReticle ctrlCommit 0; diff --git a/addons/spottingscope/rsc/spotting_scope_reticle_co.paa b/addons/spottingscope/rsc/spotting_scope_reticle_co.paa deleted file mode 100644 index a2d299d937..0000000000 Binary files a/addons/spottingscope/rsc/spotting_scope_reticle_co.paa and /dev/null differ diff --git a/addons/spottingscope/script_component.hpp b/addons/spottingscope/script_component.hpp index 14e7867285..6b2d95abbd 100644 --- a/addons/spottingscope/script_component.hpp +++ b/addons/spottingscope/script_component.hpp @@ -16,14 +16,6 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define IDC_RETICLE 10000 -#define IDC_BODY 10001 -#define IDC_BLACK_LEFT 10002 -#define IDC_BLACK_RIGHT 10003 - -#define MAGIC_SCOPE_NUMBER 0.0235 -//#define MAGIC_SCOPE_NUMBER (uiNamespace getVariable ['magic', 1]) - #define POS_X_BASE(size) safezoneX + 0.5 * safezoneW - 0.5 * (size) / (getResolution select 5) #define POS_Y_BASE(size) safezoneY + 0.5 * safezoneH - 0.5 * (size) / (getResolution select 5) * 4/3 #define POS_W_BASE(size) (size) / (getResolution select 5) diff --git a/addons/switchunits/stringtable.xml b/addons/switchunits/stringtable.xml index 539a755bc4..fab978d106 100644 --- a/addons/switchunits/stringtable.xml +++ b/addons/switchunits/stringtable.xml @@ -10,6 +10,8 @@ 병력 전환 Einheitenwechsel Przełącz Jednostki + Переключение юнитов + Trocar Unidades Switched unit diff --git a/addons/tagging/stringtable.xml b/addons/tagging/stringtable.xml index 75de55efcc..3efad87d05 100644 --- a/addons/tagging/stringtable.xml +++ b/addons/tagging/stringtable.xml @@ -12,6 +12,7 @@ Marcamento 喷漆 噴漆 + Marcação Configure how the tagging system will operate by default. @@ -24,6 +25,7 @@ Configura quanto il sistema di marcamento agirà da se. 定义喷漆系统预设设定 定義噴漆系統預設設定 + Configura como o sistema de Marcação funcionará como padrão. (Tagging) Spray Paint - Quick Tag @@ -36,6 +38,7 @@ Marcamento Rapido 快速喷漆 快速噴漆 + Lata de Tinta - Marcação Rápida Action performed on main tag interaction point. @@ -48,6 +51,7 @@ Azione eseguita sul punto di interazione dei tag principali. 直接喷漆在互动选单瞄准的点上。 直接噴漆在互動選單瞄準的點上。 + Ação executada no ponto principal de marcação Last Used @@ -60,6 +64,7 @@ Ultimo Usato 上次最后使用 上次最後使用 + Último usado Random X @@ -72,6 +77,7 @@ Random X 随机X标记 隨機X標記 + Aleatório X Random @@ -84,6 +90,7 @@ Random 随机 隨機 + Aleatório Tag diff --git a/addons/vector/CfgOpticsEffect.hpp b/addons/vector/CfgOpticsEffect.hpp new file mode 100644 index 0000000000..2b9542ba9c --- /dev/null +++ b/addons/vector/CfgOpticsEffect.hpp @@ -0,0 +1,7 @@ +class CfgOpticsEffect { + class GVAR(OpticsRadBlur1) { + type = "radialblur"; + params[] = {0.01,0.01,0.18,0.36}; + priority = 950; + }; +}; diff --git a/addons/vector/CfgVehicles.hpp b/addons/vector/CfgVehicles.hpp index 23aa8d7412..3854ea675a 100644 --- a/addons/vector/CfgVehicles.hpp +++ b/addons/vector/CfgVehicles.hpp @@ -5,16 +5,36 @@ class CfgVehicles { scope = 2; scopeCurator = 2; displayName = CSTRING(VectorName); + editorCategory = "EdCat_Equipment"; + editorSubcategory = "EdSubcat_InventoryItems"; vehicleClass = "Items"; + model = "\A3\Weapons_F\DummyBinoc.p3d"; + class TransportItems { MACRO_ADDITEM(ACE_Vector,1); }; }; + class ACE_Item_VectorDay: Item_Base_F { + author = ECSTRING(common,ACETeam); + scope = 2; + scopeCurator = 2; + displayName = CSTRING(VectorDayName); + editorCategory = "EdCat_Equipment"; + editorSubcategory = "EdSubcat_InventoryItems"; + vehicleClass = "Items"; + model = "\A3\Weapons_F\DummyBinoc.p3d"; + + class TransportItems { + MACRO_ADDITEM(ACE_VectorDay,1); + }; + }; + class Box_NATO_Support_F; class ACE_Box_Misc: Box_NATO_Support_F { class TransportItems { - MACRO_ADDITEM(ACE_Vector,6); + MACRO_ADDITEM(ACE_Vector,3); + MACRO_ADDITEM(ACE_VectorDay,3); }; }; }; diff --git a/addons/vector/CfgWeapons.hpp b/addons/vector/CfgWeapons.hpp index cc2cf985f6..5ffe99eea9 100644 --- a/addons/vector/CfgWeapons.hpp +++ b/addons/vector/CfgWeapons.hpp @@ -1,4 +1,3 @@ - class CfgWeapons { class Binocular; class ACE_Vector: Binocular { @@ -6,13 +5,24 @@ class CfgWeapons { displayName = CSTRING(VectorName); descriptionShort = CSTRING(VectorDescription); model = QPATHTOF(ace_vector.p3d); - modelOptics = QPATHTOF(ace_vector_optics.p3d); picture = QPATHTOF(UI\ace_vector_x_ca.paa); visionMode[] = {"Normal","NVG"}; - opticsZoomMax = 0.06621; - opticsZoomMin = 0.06621; + opticsZoomMax = 0.25/7; + opticsZoomMin = 0.25/7; + modelOptics = "\A3\Weapons_F\empty.p3d"; + + class CBA_ScriptedOptic { + reticleTexture = QPATHTOF(data\reticles\ace_vector_reticle_ca.paa); + reticleTextureSize = 1.026; + bodyTexture = QPATHTOF(data\reticles\ace_vector_body_co.paa); + bodyTextureSize = 1.25; + reticleSafezoneSize = 1; + hidePeripheralVision = 1; + opticsPPEffects[] = {QGVAR(OpticsRadBlur1)}; + }; weaponInfoType = "ACE_RscOptics_vector"; }; + class ACE_VectorDay: ACE_Vector { author = ECSTRING(common,ACETeam); displayName = CSTRING(VectorDayName); diff --git a/addons/vector/RscInGameUI.hpp b/addons/vector/RscInGameUI.hpp index 704dd4838c..7e2f705765 100644 --- a/addons/vector/RscInGameUI.hpp +++ b/addons/vector/RscInGameUI.hpp @@ -1,163 +1,138 @@ - class RscText; class RscPicture; - -//class ScrollBar; -class RscControlsGroup { - class VScrollbar;//: ScrollBar {}; - class HScrollbar;//: ScrollBar {}; -}; +class RscControlsGroupNoScrollbars; class RscInGameUI { - class RscUnitInfo; - class ACE_RscOptics_vector: RscUnitInfo { - onLoad = "[""onLoad"",_this,""RscUnitInfo"",'IGUI'] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable ['ACE_dlgVector', _this select 0];"; - onUnload = "[""onUnload"",_this,""RscUnitInfo"",'IGUI'] call (uinamespace getvariable 'BIS_fnc_initDisplay')"; - idd = 300; - controls[] = {"CA_Distance","CA_Heading","CA_OpticsPitch","CA_Elev","CA_OpticsZoom","CA_VisionMode","ACE_ScriptedDisplayControlsGroup"}; + class RscWeaponZeroing; + class CBA_ScriptedOptic: RscWeaponZeroing { + class CA_Zeroing; + }; + + class ACE_RscOptics_vector: CBA_ScriptedOptic { + controls[] = { + "CA_FOVMode","ScopeBlack","Reticle","BodyNight","BodyDay","TrippleHeadLeft","TrippleHeadRight","CA_Zeroing","Magnification","ActiveDisplayHelper", + "CA_Distance","CA_Heading","CA_OpticsPitch","CA_Elev","CA_OpticsZoom","CA_VisionMode","ACE_ScriptedDisplayControlsGroup" + }; class CA_Distance: RscText { - idc = 151; // distance + idc = 151; // distance w = 0; h = 0; }; - class CA_Heading: RscText { - idc = 156; // azimuth + idc = 156; // azimuth w = 0; h = 0; }; - class CA_OpticsPitch: RscText { - idc = 182; // inclination + idc = 182; // inclination w = 0; h = 0; }; - class CA_Elev: RscText { - idc = 175; // inclination, more accurate + idc = 175; // inclination, more accurate w = 0; h = 0; }; - class CA_OpticsZoom: RscText { - idc = 180; // some kind of zoom + idc = 180; // some kind of zoom w = 0; h = 0; }; - class CA_VisionMode: RscText { - idc = 179; // ??? + idc = 179; // ??? w = 0; h = 0; }; + class CA_Zeroing: CA_Zeroing { + onLoad = "(_this select 0) ctrlShow false"; + }; - class ACE_ScriptedDisplayControlsGroup: RscControlsGroup { + class ACE_ScriptedDisplayControlsGroup: RscControlsGroupNoScrollbars { + onLoad = "uiNamespace setVariable ['ACE_dlgVector', ctrlParent (_this select 0)];"; idc = 170; - x = "SafezoneX"; - y = "SafezoneY"; - w = "SafezoneW"; - h = "SafezoneH"; - - class VScrollbar: VScrollbar { - width = 0; - }; - - class HScrollbar: HScrollbar { - height = 0; - }; + x = "safezoneX"; + y = "safezoneY"; + w = "safezoneW"; + h = "safezoneH"; class controls { class Center: RscPicture { - idc = 1301; - text = ""; + idc = IDC_CENTER; colorText[] = {1,0,0,0.5}; - x = 0.488 * safezoneW /*+ safezoneX*/; - y = 0.4783 * safezoneH /*+ safezoneY*/; - w = 0.4 / 16 * safezoneW; - h = 0.4 / 9 * safezoneH; + x = "0.5 - (0.8 / 16 * safezoneW)/2 - safezoneX"; + y = "0.5 - (0.8 / 9 * safezoneH)/2 - safezoneY"; + w = "0.8 / 16 * safezoneW"; + h = "0.8 / 9 * safezoneH"; }; - class Crosshair: Center { - idc = 1302; - x = 0.4848 * safezoneW /*+ safezoneX*/; - y = 0.4732 * safezoneH /*+ safezoneY*/; - w = 0.5 / 16 * safezoneW; - h = 0.5 / 9 * safezoneH; + idc = IDC_CROSSHAIR; + x = "0.5 - (0.7 / 16 * safezoneW)/2 - safezoneX"; + y = "0.5 - (0.7 / 9 * safezoneH)/2 - safezoneY"; + w = "0.7 / 16 * safezoneW"; + h = "0.7 / 9 * safezoneH"; }; class Digit0: Center { - idc = 1310; - x = (0.54 + 0 * 0.02) * safezoneW /*+ safezoneX*/; - y = 0.54 * safezoneH /*+ safezoneY*/; - w = 0.5 / 16 * safezoneW; - h = 0.5 / 9 * safezoneH; + idc = IDC_DIGIT_0; + x = "(0.54 + 0 * 0.02) * safezoneW"; + y = "0.54 * safezoneH"; + w = "0.5 / 16 * safezoneW"; + h = "0.5 / 9 * safezoneH"; }; - class Digit1: Digit0 { - idc = 1311; - x = (0.54 + 1 * 0.02) * safezoneW /*+ safezoneX*/; + idc = IDC_DIGIT_1; + x = "(0.54 + 1 * 0.02) * safezoneW"; }; - class Digit2: Digit0 { - idc = 1312; - x = (0.54 + 2 * 0.02) * safezoneW /*+ safezoneX*/; + idc = IDC_DIGIT_2; + x = "(0.54 + 2 * 0.02) * safezoneW"; }; - class Digit3: Digit0 { - idc = 1313; - x = (0.54 + 3 * 0.02) * safezoneW /*+ safezoneX*/; + idc = IDC_DIGIT_3; + x = "(0.54 + 3 * 0.02) * safezoneW"; }; - class Digit4: Digit0 { - idc = 1314; - x = (0.54 + 4 * 0.02) * safezoneW /*+ safezoneX*/; + idc = IDC_DIGIT_4; + x = "(0.54 + 4 * 0.02) * safezoneW"; }; - class Digit5: Digit0 { - idc = 1315; - x = (0.35 + 0 * 0.02) * safezoneW /*+ safezoneX*/; + idc = IDC_DIGIT_5; + x = "(0.35 + 0 * 0.02) * safezoneW"; }; - class Digit6: Digit0 { - idc = 1316; - x = (0.35 + 1 * 0.02) * safezoneW /*+ safezoneX*/; + idc = IDC_DIGIT_6; + x = "(0.35 + 1 * 0.02) * safezoneW"; }; - class Digit7: Digit0 { - idc = 1317; - x = (0.35 + 2 * 0.02) * safezoneW /*+ safezoneX*/; + idc = IDC_DIGIT_7; + x = "(0.35 + 2 * 0.02) * safezoneW"; }; - class Digit8: Digit0 { - idc = 1318; - x = (0.35 + 3 * 0.02) * safezoneW /*+ safezoneX*/; + idc = IDC_DIGIT_8; + x = "(0.35 + 3 * 0.02) * safezoneW"; }; - class Digit9: Digit0 { - idc = 1319; - x = (0.35 + 4 * 0.02) * safezoneW /*+ safezoneX*/; + idc = IDC_DIGIT_9; + x = "(0.35 + 4 * 0.02) * safezoneW"; }; class DigitE1: Digit0 { - idc = 1321; - x = (0.39 + 0 * 0.02) * safezoneW /*+ safezoneX*/; - y = 0.42 * safezoneH /*+ safezoneY*/; + idc = IDC_DIGIT_E1; + x = "(0.39 + 0 * 0.02) * safezoneW"; + y = "0.42 * safezoneH"; }; - class DigitE2: DigitE1 { - idc = 1322; - x = (0.39 + 1 * 0.02) * safezoneW /*+ safezoneX*/; + idc = IDC_DIGIT_E2; + x = "(0.39 + 1 * 0.02) * safezoneW"; }; - class DigitE3: DigitE1 { - idc = 1323; - x = (0.39 + 2 * 0.02) * safezoneW /*+ safezoneX*/; + idc = IDC_DIGIT_E3; + x = "(0.39 + 2 * 0.02) * safezoneW"; }; - class DigitE4: DigitE1 { - idc = 1324; - x = (0.39 + 3 * 0.02) * safezoneW /*+ safezoneX*/; + idc = IDC_DIGIT_E4; + x = "(0.39 + 3 * 0.02) * safezoneW"; }; }; }; diff --git a/addons/vector/XEH_PREP.hpp b/addons/vector/XEH_PREP.hpp index f03d99ed83..1f259e3ff9 100644 --- a/addons/vector/XEH_PREP.hpp +++ b/addons/vector/XEH_PREP.hpp @@ -1,4 +1,3 @@ - PREP(clearDisplay); PREP(convertToTexturesDegree); PREP(convertToTexturesDistance); diff --git a/addons/vector/ace_vector_optics.p3d b/addons/vector/ace_vector_optics.p3d deleted file mode 100644 index 15cfb1c910..0000000000 Binary files a/addons/vector/ace_vector_optics.p3d and /dev/null differ diff --git a/addons/vector/config.cpp b/addons/vector/config.cpp index cf6f235a5e..10371047e6 100644 --- a/addons/vector/config.cpp +++ b/addons/vector/config.cpp @@ -3,8 +3,8 @@ class CfgPatches { class ADDON { name = COMPONENT_NAME; - units[] = {"ACE_Item_Vector"}; - weapons[] = {"ACE_Vector", "ACE_VectorDay"}; + units[] = {"ACE_Item_Vector","ACE_Item_VectorDay"}; + weapons[] = {"ACE_Vector","ACE_VectorDay"}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_common"}; author = ECSTRING(common,ACETeam); @@ -15,8 +15,11 @@ class CfgPatches { }; #include "CfgEventHandlers.hpp" - #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" - +#include "CfgOpticsEffect.hpp" #include "RscInGameUI.hpp" + +class CBA_PIPItems { + GVAR(enable) = "-"; +}; diff --git a/addons/vector/data/reticles/ace_vector_body_co.paa b/addons/vector/data/reticles/ace_vector_body_co.paa new file mode 100644 index 0000000000..71e1984c6e Binary files /dev/null and b/addons/vector/data/reticles/ace_vector_body_co.paa differ diff --git a/addons/vector/data/reticles/ace_vector_reticle.paa b/addons/vector/data/reticles/ace_vector_reticle.paa deleted file mode 100644 index 425dbb85b2..0000000000 Binary files a/addons/vector/data/reticles/ace_vector_reticle.paa and /dev/null differ diff --git a/addons/vector/data/reticles/ace_vector_reticle_1_ca.paa b/addons/vector/data/reticles/ace_vector_reticle_1_ca.paa new file mode 100644 index 0000000000..255d8fa338 Binary files /dev/null and b/addons/vector/data/reticles/ace_vector_reticle_1_ca.paa differ diff --git a/addons/vector/data/reticles/ace_vector_reticle_2_ca.paa b/addons/vector/data/reticles/ace_vector_reticle_2_ca.paa new file mode 100644 index 0000000000..98ab3d04ba Binary files /dev/null and b/addons/vector/data/reticles/ace_vector_reticle_2_ca.paa differ diff --git a/addons/vector/data/reticles/ace_vector_reticle_3_ca.paa b/addons/vector/data/reticles/ace_vector_reticle_3_ca.paa new file mode 100644 index 0000000000..85d4e6940d Binary files /dev/null and b/addons/vector/data/reticles/ace_vector_reticle_3_ca.paa differ diff --git a/addons/vector/data/reticles/ace_vector_reticle_4_ca.paa b/addons/vector/data/reticles/ace_vector_reticle_4_ca.paa new file mode 100644 index 0000000000..85a38b4145 Binary files /dev/null and b/addons/vector/data/reticles/ace_vector_reticle_4_ca.paa differ diff --git a/addons/vector/data/reticles/ace_vector_reticle_5_ca.paa b/addons/vector/data/reticles/ace_vector_reticle_5_ca.paa new file mode 100644 index 0000000000..ff4f89edd4 Binary files /dev/null and b/addons/vector/data/reticles/ace_vector_reticle_5_ca.paa differ diff --git a/addons/vector/data/reticles/ace_vector_reticle_ca.paa b/addons/vector/data/reticles/ace_vector_reticle_ca.paa new file mode 100644 index 0000000000..4db7c71ff6 Binary files /dev/null and b/addons/vector/data/reticles/ace_vector_reticle_ca.paa differ diff --git a/addons/vector/functions/fnc_adjustBrightness.sqf b/addons/vector/functions/fnc_adjustBrightness.sqf index 2cf2d5a923..cfe7f119a8 100644 --- a/addons/vector/functions/fnc_adjustBrightness.sqf +++ b/addons/vector/functions/fnc_adjustBrightness.sqf @@ -20,22 +20,22 @@ private _dlgVector = GETUVAR(ACE_dlgVector,displayNull); private _color = [[1,0,0,0.5], [1,0,0,1]] select (_this select 0); -(_dlgVector displayCtrl 1301) ctrlSetTextColor _color; -(_dlgVector displayCtrl 1302) ctrlSetTextColor _color; -(_dlgVector displayCtrl 1310) ctrlSetTextColor _color; -(_dlgVector displayCtrl 1311) ctrlSetTextColor _color; -(_dlgVector displayCtrl 1312) ctrlSetTextColor _color; -(_dlgVector displayCtrl 1313) ctrlSetTextColor _color; -(_dlgVector displayCtrl 1314) ctrlSetTextColor _color; -(_dlgVector displayCtrl 1315) ctrlSetTextColor _color; -(_dlgVector displayCtrl 1316) ctrlSetTextColor _color; -(_dlgVector displayCtrl 1317) ctrlSetTextColor _color; -(_dlgVector displayCtrl 1318) ctrlSetTextColor _color; -(_dlgVector displayCtrl 1319) ctrlSetTextColor _color; -(_dlgVector displayCtrl 1321) ctrlSetTextColor _color; -(_dlgVector displayCtrl 1322) ctrlSetTextColor _color; -(_dlgVector displayCtrl 1323) ctrlSetTextColor _color; -(_dlgVector displayCtrl 1324) ctrlSetTextColor _color; +(_dlgVector displayCtrl IDC_CENTER) ctrlSetTextColor _color; +(_dlgVector displayCtrl IDC_CROSSHAIR) ctrlSetTextColor _color; +(_dlgVector displayCtrl IDC_DIGIT_0) ctrlSetTextColor _color; +(_dlgVector displayCtrl IDC_DIGIT_1) ctrlSetTextColor _color; +(_dlgVector displayCtrl IDC_DIGIT_2) ctrlSetTextColor _color; +(_dlgVector displayCtrl IDC_DIGIT_3) ctrlSetTextColor _color; +(_dlgVector displayCtrl IDC_DIGIT_4) ctrlSetTextColor _color; +(_dlgVector displayCtrl IDC_DIGIT_5) ctrlSetTextColor _color; +(_dlgVector displayCtrl IDC_DIGIT_6) ctrlSetTextColor _color; +(_dlgVector displayCtrl IDC_DIGIT_7) ctrlSetTextColor _color; +(_dlgVector displayCtrl IDC_DIGIT_8) ctrlSetTextColor _color; +(_dlgVector displayCtrl IDC_DIGIT_9) ctrlSetTextColor _color; +(_dlgVector displayCtrl IDC_DIGIT_E1) ctrlSetTextColor _color; +(_dlgVector displayCtrl IDC_DIGIT_E2) ctrlSetTextColor _color; +(_dlgVector displayCtrl IDC_DIGIT_E3) ctrlSetTextColor _color; +(_dlgVector displayCtrl IDC_DIGIT_E4) ctrlSetTextColor _color; GVAR(illuminate) = _this select 0; diff --git a/addons/vector/functions/fnc_clearDisplay.sqf b/addons/vector/functions/fnc_clearDisplay.sqf index 8d4578a2da..1f723dd2f8 100644 --- a/addons/vector/functions/fnc_clearDisplay.sqf +++ b/addons/vector/functions/fnc_clearDisplay.sqf @@ -20,18 +20,18 @@ private _dlgVector = GETUVAR(ACE_dlgVector,displayNull); switch (_this select 0) do { case ("azimuth"): { - (_dlgVector displayCtrl 1315) ctrlSetText ""; - (_dlgVector displayCtrl 1316) ctrlSetText ""; - (_dlgVector displayCtrl 1317) ctrlSetText ""; - (_dlgVector displayCtrl 1318) ctrlSetText ""; - (_dlgVector displayCtrl 1319) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_5) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_6) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_7) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_8) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_9) ctrlSetText ""; }; case ("distance"): { - (_dlgVector displayCtrl 1310) ctrlSetText ""; - (_dlgVector displayCtrl 1311) ctrlSetText ""; - (_dlgVector displayCtrl 1312) ctrlSetText ""; - (_dlgVector displayCtrl 1313) ctrlSetText ""; - (_dlgVector displayCtrl 1314) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_0) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_1) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_2) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_3) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_4) ctrlSetText ""; }; }; diff --git a/addons/vector/functions/fnc_getRelativeHeightLength.sqf b/addons/vector/functions/fnc_getRelativeHeightLength.sqf index 2bd6e4795c..1049ba84b6 100644 --- a/addons/vector/functions/fnc_getRelativeHeightLength.sqf +++ b/addons/vector/functions/fnc_getRelativeHeightLength.sqf @@ -15,24 +15,20 @@ * Public: No */ -private _distanceP1 = GVAR(pData) select 0; -private _directionP1 = GVAR(pData) select 1; -private _azimuthP1 = _directionP1 select 0; -private _inclinationP1 = _directionP1 select 1; +GVAR(pData) params ["_distanceP1", "_directionP1"]; +_directionP1 params ["_azimuthP1", "_inclinationP1"]; private _distanceP2 = call FUNC(getDistance); private _directionP2 = call FUNC(getDirection); -private _azimuthP2 = _directionP2 select 0; -private _inclinationP2 = _directionP2 select 1; - -private _azimuth = abs (_azimuthP1 - _azimuthP2); -private _inclination = abs (_inclinationP1 - _inclinationP2); -private _height = sqrt (_distanceP1 ^ 2 + _distanceP2 ^ 2 - 2 * _distanceP1 * _distanceP2 * cos _inclination); -private _length = sqrt (_distanceP1 ^ 2 + _distanceP2 ^ 2 - 2 * _distanceP1 * _distanceP2 * cos _azimuth); - -if (_inclination < 0) then {_height = -1 * _height}; +_directionP2 params ["_azimuthP2", "_inclinationP2"]; if (_distanceP1 < -999 || {_distanceP2 < -999}) exitWith { [-1000, -1000] // return }; +private _position1 = [_distanceP1, _azimuthP1, _inclinationP1] call CBA_fnc_polar2vect; +private _position2 = [_distanceP2, _azimuthP2, _inclinationP2] call CBA_fnc_polar2vect; + +private _length = _position1 distance2D _position2; +private _height = abs ((_position1 vectorDiff _position2) select 2); + [_height, _length] diff --git a/addons/vector/functions/fnc_illuminate.sqf b/addons/vector/functions/fnc_illuminate.sqf index 999fc5c29a..0c91da0ac0 100644 --- a/addons/vector/functions/fnc_illuminate.sqf +++ b/addons/vector/functions/fnc_illuminate.sqf @@ -20,31 +20,28 @@ private _dlgVector = GETUVAR(ACE_dlgVector,displayNull); if (_this select 0) then { { - if (ctrlIDC _x != 170) then { - private _string = ctrlText _x; - private _index = _string find ".paa"; + private _control = _dlgVector displayCtrl _x; + private _string = ctrlText _control; + private _index = _string find ".paa"; - if (_index != -1 && {_string find "_illum.paa" == -1}) then { - _string = toArray _string; - _string resize _index; + if (_index != -1 && {_string find "_illum.paa" == -1}) then { + _string = toArray _string; + _string resize _index; - _x ctrlSetText format ["%1_illum.paa", toString _string]; - }; + _control ctrlSetText format ["%1_illum.paa", toString _string]; }; - } forEach allControls _dlgVector; + } forEach ILLUM_CONTROLS; } else { { - if (ctrlIDC _x != 170) then { - private _string = ctrlText _x; - private _index = _string find "_illum.paa"; + private _control = _dlgVector displayCtrl _x; + private _string = ctrlText _control; + private _index = _string find "_illum.paa"; - if (_index != -1) then { - _string = toArray _string; - _string resize _index; - - _x ctrlSetText format ["%1.paa", toString _string]; - }; + if (_index != -1) then { + _string = toArray _string; + _string resize _index; + _control ctrlSetText format ["%1.paa", toString _string]; }; - } forEach allControls _dlgVector; + } forEach ILLUM_CONTROLS; }; diff --git a/addons/vector/functions/fnc_showAzimuth.sqf b/addons/vector/functions/fnc_showAzimuth.sqf index 4a0854f3d5..e07f093b5d 100644 --- a/addons/vector/functions/fnc_showAzimuth.sqf +++ b/addons/vector/functions/fnc_showAzimuth.sqf @@ -22,9 +22,9 @@ private _direction = call FUNC(getDirection); private _digits = _direction call FUNC(convertToTexturesDegree); -(_dlgVector displayCtrl 1315) ctrlSetText (_digits select 0); -(_dlgVector displayCtrl 1316) ctrlSetText (_digits select 1); -(_dlgVector displayCtrl 1317) ctrlSetText (_digits select 2); -(_dlgVector displayCtrl 1318) ctrlSetText (_digits select 3); +(_dlgVector displayCtrl IDC_DIGIT_5) ctrlSetText (_digits select 0); +(_dlgVector displayCtrl IDC_DIGIT_6) ctrlSetText (_digits select 1); +(_dlgVector displayCtrl IDC_DIGIT_7) ctrlSetText (_digits select 2); +(_dlgVector displayCtrl IDC_DIGIT_8) ctrlSetText (_digits select 3); [GVAR(illuminate)] call FUNC(illuminate); diff --git a/addons/vector/functions/fnc_showAzimuthInclination.sqf b/addons/vector/functions/fnc_showAzimuthInclination.sqf index 15e206fbbd..e7769a3e7b 100644 --- a/addons/vector/functions/fnc_showAzimuthInclination.sqf +++ b/addons/vector/functions/fnc_showAzimuthInclination.sqf @@ -23,17 +23,17 @@ private _direction = call FUNC(getDirection); // azimuth private _digits = [_direction select 0] call FUNC(convertToTexturesDegree); -(_dlgVector displayCtrl 1315) ctrlSetText (_digits select 0); -(_dlgVector displayCtrl 1316) ctrlSetText (_digits select 1); -(_dlgVector displayCtrl 1317) ctrlSetText (_digits select 2); -(_dlgVector displayCtrl 1318) ctrlSetText (_digits select 3); +(_dlgVector displayCtrl IDC_DIGIT_5) ctrlSetText (_digits select 0); +(_dlgVector displayCtrl IDC_DIGIT_6) ctrlSetText (_digits select 1); +(_dlgVector displayCtrl IDC_DIGIT_7) ctrlSetText (_digits select 2); +(_dlgVector displayCtrl IDC_DIGIT_8) ctrlSetText (_digits select 3); // inclination _digits = [_direction select 1] call FUNC(convertToTexturesDegree); -(_dlgVector displayCtrl 1311) ctrlSetText (_digits select 0); -(_dlgVector displayCtrl 1312) ctrlSetText (_digits select 1); -(_dlgVector displayCtrl 1313) ctrlSetText (_digits select 2); -(_dlgVector displayCtrl 1314) ctrlSetText (_digits select 3); +(_dlgVector displayCtrl IDC_DIGIT_1) ctrlSetText (_digits select 0); +(_dlgVector displayCtrl IDC_DIGIT_2) ctrlSetText (_digits select 1); +(_dlgVector displayCtrl IDC_DIGIT_3) ctrlSetText (_digits select 2); +(_dlgVector displayCtrl IDC_DIGIT_4) ctrlSetText (_digits select 3); [GVAR(illuminate)] call FUNC(illuminate); diff --git a/addons/vector/functions/fnc_showCenter.sqf b/addons/vector/functions/fnc_showCenter.sqf index fef128240f..d9e3542fac 100644 --- a/addons/vector/functions/fnc_showCenter.sqf +++ b/addons/vector/functions/fnc_showCenter.sqf @@ -15,6 +15,6 @@ * Public: No */ -((GETUVAR(ACE_dlgVector,displayNull)) displayCtrl 1301) ctrlSetText (["", QPATHTOF(rsc\vector_center.paa)] select (_this select 0)); +((GETUVAR(ACE_dlgVector,displayNull)) displayCtrl IDC_CENTER) ctrlSetText (["", QPATHTOF(rsc\vector_center.paa)] select (_this select 0)); [GVAR(illuminate)] call FUNC(illuminate); diff --git a/addons/vector/functions/fnc_showDistance.sqf b/addons/vector/functions/fnc_showDistance.sqf index 447622355c..3009d5ea5d 100644 --- a/addons/vector/functions/fnc_showDistance.sqf +++ b/addons/vector/functions/fnc_showDistance.sqf @@ -22,9 +22,9 @@ private _distance = call FUNC(getDistance); private _digits = [_distance] call FUNC(convertToTexturesDistance); -(_dlgVector displayCtrl 1311) ctrlSetText (_digits select 0); -(_dlgVector displayCtrl 1312) ctrlSetText (_digits select 1); -(_dlgVector displayCtrl 1313) ctrlSetText (_digits select 2); -(_dlgVector displayCtrl 1314) ctrlSetText (_digits select 3); +(_dlgVector displayCtrl IDC_DIGIT_1) ctrlSetText (_digits select 0); +(_dlgVector displayCtrl IDC_DIGIT_2) ctrlSetText (_digits select 1); +(_dlgVector displayCtrl IDC_DIGIT_3) ctrlSetText (_digits select 2); +(_dlgVector displayCtrl IDC_DIGIT_4) ctrlSetText (_digits select 3); [GVAR(illuminate)] call FUNC(illuminate); diff --git a/addons/vector/functions/fnc_showFallOfShot.sqf b/addons/vector/functions/fnc_showFallOfShot.sqf index 3df9fa8357..ac03fc6bbf 100644 --- a/addons/vector/functions/fnc_showFallOfShot.sqf +++ b/addons/vector/functions/fnc_showFallOfShot.sqf @@ -26,37 +26,37 @@ if !(_this select 0) then { // of ordinate private _digits = [_fosData, 1] call FUNC(convertToTexturesFOS); - (_dlgVector displayCtrl 1310) ctrlSetText (_digits select 0); - (_dlgVector displayCtrl 1311) ctrlSetText (_digits select 1); - (_dlgVector displayCtrl 1312) ctrlSetText (_digits select 2); - (_dlgVector displayCtrl 1313) ctrlSetText (_digits select 3); - (_dlgVector displayCtrl 1314) ctrlSetText (_digits select 4); + (_dlgVector displayCtrl IDC_DIGIT_0) ctrlSetText (_digits select 0); + (_dlgVector displayCtrl IDC_DIGIT_1) ctrlSetText (_digits select 1); + (_dlgVector displayCtrl IDC_DIGIT_2) ctrlSetText (_digits select 2); + (_dlgVector displayCtrl IDC_DIGIT_3) ctrlSetText (_digits select 3); + (_dlgVector displayCtrl IDC_DIGIT_4) ctrlSetText (_digits select 4); // of abscissa _digits = [_fosData, 0] call FUNC(convertToTexturesFOS); - (_dlgVector displayCtrl 1315) ctrlSetText (_digits select 0); - (_dlgVector displayCtrl 1316) ctrlSetText (_digits select 1); - (_dlgVector displayCtrl 1317) ctrlSetText (_digits select 2); - (_dlgVector displayCtrl 1318) ctrlSetText (_digits select 3); - (_dlgVector displayCtrl 1319) ctrlSetText (_digits select 4); + (_dlgVector displayCtrl IDC_DIGIT_5) ctrlSetText (_digits select 0); + (_dlgVector displayCtrl IDC_DIGIT_6) ctrlSetText (_digits select 1); + (_dlgVector displayCtrl IDC_DIGIT_7) ctrlSetText (_digits select 2); + (_dlgVector displayCtrl IDC_DIGIT_8) ctrlSetText (_digits select 3); + (_dlgVector displayCtrl IDC_DIGIT_9) ctrlSetText (_digits select 4); } else { // applicate private _digits = [_fosData, 2] call FUNC(convertToTexturesFOS); - (_dlgVector displayCtrl 1310) ctrlSetText (_digits select 0); - (_dlgVector displayCtrl 1311) ctrlSetText (_digits select 1); - (_dlgVector displayCtrl 1312) ctrlSetText (_digits select 2); - (_dlgVector displayCtrl 1313) ctrlSetText (_digits select 3); - (_dlgVector displayCtrl 1314) ctrlSetText (_digits select 4); + (_dlgVector displayCtrl IDC_DIGIT_0) ctrlSetText (_digits select 0); + (_dlgVector displayCtrl IDC_DIGIT_1) ctrlSetText (_digits select 1); + (_dlgVector displayCtrl IDC_DIGIT_2) ctrlSetText (_digits select 2); + (_dlgVector displayCtrl IDC_DIGIT_3) ctrlSetText (_digits select 3); + (_dlgVector displayCtrl IDC_DIGIT_4) ctrlSetText (_digits select 4); // nothing - (_dlgVector displayCtrl 1315) ctrlSetText ""; - (_dlgVector displayCtrl 1316) ctrlSetText ""; - (_dlgVector displayCtrl 1317) ctrlSetText ""; - (_dlgVector displayCtrl 1318) ctrlSetText ""; - (_dlgVector displayCtrl 1319) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_5) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_6) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_7) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_8) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_9) ctrlSetText ""; }; diff --git a/addons/vector/functions/fnc_showHeightDistance.sqf b/addons/vector/functions/fnc_showHeightDistance.sqf index 7c8c0cc02e..ce4e3011a9 100644 --- a/addons/vector/functions/fnc_showHeightDistance.sqf +++ b/addons/vector/functions/fnc_showHeightDistance.sqf @@ -23,17 +23,17 @@ private _heightDistance = call FUNC(getHeightDistance); // height private _digits = [_heightDistance select 0] call FUNC(convertToTexturesDistance); -(_dlgVector displayCtrl 1311) ctrlSetText (_digits select 0); -(_dlgVector displayCtrl 1312) ctrlSetText (_digits select 1); -(_dlgVector displayCtrl 1313) ctrlSetText (_digits select 2); -(_dlgVector displayCtrl 1314) ctrlSetText (_digits select 3); +(_dlgVector displayCtrl IDC_DIGIT_1) ctrlSetText (_digits select 0); +(_dlgVector displayCtrl IDC_DIGIT_2) ctrlSetText (_digits select 1); +(_dlgVector displayCtrl IDC_DIGIT_3) ctrlSetText (_digits select 2); +(_dlgVector displayCtrl IDC_DIGIT_4) ctrlSetText (_digits select 3); // non-slope distance _digits = [_heightDistance select 1] call FUNC(convertToTexturesDistance); -(_dlgVector displayCtrl 1315) ctrlSetText (_digits select 0); -(_dlgVector displayCtrl 1316) ctrlSetText (_digits select 1); -(_dlgVector displayCtrl 1317) ctrlSetText (_digits select 2); -(_dlgVector displayCtrl 1318) ctrlSetText (_digits select 3); +(_dlgVector displayCtrl IDC_DIGIT_5) ctrlSetText (_digits select 0); +(_dlgVector displayCtrl IDC_DIGIT_6) ctrlSetText (_digits select 1); +(_dlgVector displayCtrl IDC_DIGIT_7) ctrlSetText (_digits select 2); +(_dlgVector displayCtrl IDC_DIGIT_8) ctrlSetText (_digits select 3); [GVAR(illuminate)] call FUNC(illuminate); diff --git a/addons/vector/functions/fnc_showP1.sqf b/addons/vector/functions/fnc_showP1.sqf index 2d587e03d1..4cb25adfaa 100644 --- a/addons/vector/functions/fnc_showP1.sqf +++ b/addons/vector/functions/fnc_showP1.sqf @@ -19,15 +19,15 @@ disableSerialization; private _dlgVector = GETUVAR(ACE_dlgVector,displayNull); if (_this select 0) then { - (_dlgVector displayCtrl 1321) ctrlSetText QPATHTOF(rsc\vector_1.paa); - (_dlgVector displayCtrl 1322) ctrlSetText QPATHTOF(rsc\vector_minus.paa); - (_dlgVector displayCtrl 1323) ctrlSetText QPATHTOF(rsc\vector_p.paa); - (_dlgVector displayCtrl 1324) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_E1) ctrlSetText QPATHTOF(rsc\vector_1.paa); + (_dlgVector displayCtrl IDC_DIGIT_E2) ctrlSetText QPATHTOF(rsc\vector_minus.paa); + (_dlgVector displayCtrl IDC_DIGIT_E3) ctrlSetText QPATHTOF(rsc\vector_p.paa); + (_dlgVector displayCtrl IDC_DIGIT_E4) ctrlSetText ""; } else { - (_dlgVector displayCtrl 1321) ctrlSetText ""; - (_dlgVector displayCtrl 1322) ctrlSetText ""; - (_dlgVector displayCtrl 1323) ctrlSetText ""; - (_dlgVector displayCtrl 1324) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_E1) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_E2) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_E3) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_E4) ctrlSetText ""; }; [GVAR(illuminate)] call FUNC(illuminate); diff --git a/addons/vector/functions/fnc_showRelativeAzimuthDistance.sqf b/addons/vector/functions/fnc_showRelativeAzimuthDistance.sqf index 82f1f7eaf6..74365cc6c7 100644 --- a/addons/vector/functions/fnc_showRelativeAzimuthDistance.sqf +++ b/addons/vector/functions/fnc_showRelativeAzimuthDistance.sqf @@ -23,17 +23,17 @@ private _azimuthDistance = call FUNC(getRelativeAzimuthDistance); // relative azimuth private _digits = [_azimuthDistance select 0] call FUNC(convertToTexturesDegree); -(_dlgVector displayCtrl 1315) ctrlSetText (_digits select 0); -(_dlgVector displayCtrl 1316) ctrlSetText (_digits select 1); -(_dlgVector displayCtrl 1317) ctrlSetText (_digits select 2); -(_dlgVector displayCtrl 1318) ctrlSetText (_digits select 3); +(_dlgVector displayCtrl IDC_DIGIT_5) ctrlSetText (_digits select 0); +(_dlgVector displayCtrl IDC_DIGIT_6) ctrlSetText (_digits select 1); +(_dlgVector displayCtrl IDC_DIGIT_7) ctrlSetText (_digits select 2); +(_dlgVector displayCtrl IDC_DIGIT_8) ctrlSetText (_digits select 3); // relative non-slope distance _digits = [_azimuthDistance select 1] call FUNC(convertToTexturesDistance); -(_dlgVector displayCtrl 1311) ctrlSetText (_digits select 0); -(_dlgVector displayCtrl 1312) ctrlSetText (_digits select 1); -(_dlgVector displayCtrl 1313) ctrlSetText (_digits select 2); -(_dlgVector displayCtrl 1314) ctrlSetText (_digits select 3); +(_dlgVector displayCtrl IDC_DIGIT_1) ctrlSetText (_digits select 0); +(_dlgVector displayCtrl IDC_DIGIT_2) ctrlSetText (_digits select 1); +(_dlgVector displayCtrl IDC_DIGIT_3) ctrlSetText (_digits select 2); +(_dlgVector displayCtrl IDC_DIGIT_4) ctrlSetText (_digits select 3); [GVAR(illuminate)] call FUNC(illuminate); diff --git a/addons/vector/functions/fnc_showRelativeDistance.sqf b/addons/vector/functions/fnc_showRelativeDistance.sqf index 0bd4d23ec0..b8ddd9f04f 100644 --- a/addons/vector/functions/fnc_showRelativeDistance.sqf +++ b/addons/vector/functions/fnc_showRelativeDistance.sqf @@ -23,7 +23,7 @@ private _distance = call FUNC(getRelativeDistance); // relative slope distance private _digits = [_distance] call FUNC(convertToTexturesDistance); -(_dlgVector displayCtrl 1311) ctrlSetText (_digits select 0); -(_dlgVector displayCtrl 1312) ctrlSetText (_digits select 1); -(_dlgVector displayCtrl 1313) ctrlSetText (_digits select 2); -(_dlgVector displayCtrl 1314) ctrlSetText (_digits select 3); +(_dlgVector displayCtrl IDC_DIGIT_1) ctrlSetText (_digits select 0); +(_dlgVector displayCtrl IDC_DIGIT_2) ctrlSetText (_digits select 1); +(_dlgVector displayCtrl IDC_DIGIT_3) ctrlSetText (_digits select 2); +(_dlgVector displayCtrl IDC_DIGIT_4) ctrlSetText (_digits select 3); diff --git a/addons/vector/functions/fnc_showRelativeHeightLength.sqf b/addons/vector/functions/fnc_showRelativeHeightLength.sqf index fe9823e170..1fb9ddcb2f 100644 --- a/addons/vector/functions/fnc_showRelativeHeightLength.sqf +++ b/addons/vector/functions/fnc_showRelativeHeightLength.sqf @@ -23,17 +23,17 @@ private _heightLength = call FUNC(getRelativeHeightLength); // height private _digits = [_heightLength select 0] call FUNC(convertToTexturesDistance); -(_dlgVector displayCtrl 1311) ctrlSetText (_digits select 0); -(_dlgVector displayCtrl 1312) ctrlSetText (_digits select 1); -(_dlgVector displayCtrl 1313) ctrlSetText (_digits select 2); -(_dlgVector displayCtrl 1314) ctrlSetText (_digits select 3); +(_dlgVector displayCtrl IDC_DIGIT_1) ctrlSetText (_digits select 0); +(_dlgVector displayCtrl IDC_DIGIT_2) ctrlSetText (_digits select 1); +(_dlgVector displayCtrl IDC_DIGIT_3) ctrlSetText (_digits select 2); +(_dlgVector displayCtrl IDC_DIGIT_4) ctrlSetText (_digits select 3); // length _digits = [_heightLength select 1] call FUNC(convertToTexturesDistance); -(_dlgVector displayCtrl 1315) ctrlSetText (_digits select 0); -(_dlgVector displayCtrl 1316) ctrlSetText (_digits select 1); -(_dlgVector displayCtrl 1317) ctrlSetText (_digits select 2); -(_dlgVector displayCtrl 1318) ctrlSetText (_digits select 3); +(_dlgVector displayCtrl IDC_DIGIT_5) ctrlSetText (_digits select 0); +(_dlgVector displayCtrl IDC_DIGIT_6) ctrlSetText (_digits select 1); +(_dlgVector displayCtrl IDC_DIGIT_7) ctrlSetText (_digits select 2); +(_dlgVector displayCtrl IDC_DIGIT_8) ctrlSetText (_digits select 3); [GVAR(illuminate)] call FUNC(illuminate); diff --git a/addons/vector/functions/fnc_showReticle.sqf b/addons/vector/functions/fnc_showReticle.sqf index 5fd1729c4f..fabf3cad15 100644 --- a/addons/vector/functions/fnc_showReticle.sqf +++ b/addons/vector/functions/fnc_showReticle.sqf @@ -15,6 +15,6 @@ * Public: No */ -((GETUVAR(ACE_dlgVector,displayNull)) displayCtrl 1302) ctrlSetText (["", QPATHTOF(rsc\vector_crosshair.paa)] select (_this select 0)); +((GETUVAR(ACE_dlgVector,displayNull)) displayCtrl IDC_CROSSHAIR) ctrlSetText (["", QPATHTOF(rsc\vector_crosshair.paa)] select (_this select 0)); [GVAR(illuminate)] call FUNC(illuminate); diff --git a/addons/vector/functions/fnc_showText.sqf b/addons/vector/functions/fnc_showText.sqf index a8556e7a58..23f4481082 100644 --- a/addons/vector/functions/fnc_showText.sqf +++ b/addons/vector/functions/fnc_showText.sqf @@ -20,149 +20,149 @@ private _dlgVector = GETUVAR(ACE_dlgVector,displayNull); switch (_this select 0) do { case ("config"): { - (_dlgVector displayCtrl 1315) ctrlSetText ""; - (_dlgVector displayCtrl 1316) ctrlSetText ""; - (_dlgVector displayCtrl 1317) ctrlSetText QPATHTOF(rsc\vector_c.paa); - (_dlgVector displayCtrl 1318) ctrlSetText QPATHTOF(rsc\vector_o.paa); - (_dlgVector displayCtrl 1319) ctrlSetText QPATHTOF(rsc\vector_n.paa); - (_dlgVector displayCtrl 1310) ctrlSetText QPATHTOF(rsc\vector_f.paa); - (_dlgVector displayCtrl 1311) ctrlSetText QPATHTOF(rsc\vector_i.paa); - (_dlgVector displayCtrl 1312) ctrlSetText QPATHTOF(rsc\vector_g.paa); - (_dlgVector displayCtrl 1313) ctrlSetText ""; - (_dlgVector displayCtrl 1314) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_5) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_6) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_7) ctrlSetText QPATHTOF(rsc\vector_c.paa); + (_dlgVector displayCtrl IDC_DIGIT_8) ctrlSetText QPATHTOF(rsc\vector_o.paa); + (_dlgVector displayCtrl IDC_DIGIT_9) ctrlSetText QPATHTOF(rsc\vector_n.paa); + (_dlgVector displayCtrl IDC_DIGIT_0) ctrlSetText QPATHTOF(rsc\vector_f.paa); + (_dlgVector displayCtrl IDC_DIGIT_1) ctrlSetText QPATHTOF(rsc\vector_i.paa); + (_dlgVector displayCtrl IDC_DIGIT_2) ctrlSetText QPATHTOF(rsc\vector_g.paa); + (_dlgVector displayCtrl IDC_DIGIT_3) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_4) ctrlSetText ""; }; case ("settings"): { - (_dlgVector displayCtrl 1315) ctrlSetText ""; - (_dlgVector displayCtrl 1316) ctrlSetText QPATHTOF(rsc\vector_u.paa); - (_dlgVector displayCtrl 1317) ctrlSetText QPATHTOF(rsc\vector_n.paa); - (_dlgVector displayCtrl 1318) ctrlSetText QPATHTOF(rsc\vector_i.paa); - (_dlgVector displayCtrl 1319) ctrlSetText QPATHTOF(rsc\vector_t.paa); - (_dlgVector displayCtrl 1310) ctrlSetText QPATHTOF(rsc\vector_5.paa); - (_dlgVector displayCtrl 1311) ctrlSetText QPATHTOF(rsc\vector_e.paa); - (_dlgVector displayCtrl 1312) ctrlSetText QPATHTOF(rsc\vector_t.paa); - (_dlgVector displayCtrl 1313) ctrlSetText QPATHTOF(rsc\vector_t.paa); - (_dlgVector displayCtrl 1314) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_5) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_6) ctrlSetText QPATHTOF(rsc\vector_u.paa); + (_dlgVector displayCtrl IDC_DIGIT_7) ctrlSetText QPATHTOF(rsc\vector_n.paa); + (_dlgVector displayCtrl IDC_DIGIT_8) ctrlSetText QPATHTOF(rsc\vector_i.paa); + (_dlgVector displayCtrl IDC_DIGIT_9) ctrlSetText QPATHTOF(rsc\vector_t.paa); + (_dlgVector displayCtrl IDC_DIGIT_0) ctrlSetText QPATHTOF(rsc\vector_5.paa); + (_dlgVector displayCtrl IDC_DIGIT_1) ctrlSetText QPATHTOF(rsc\vector_e.paa); + (_dlgVector displayCtrl IDC_DIGIT_2) ctrlSetText QPATHTOF(rsc\vector_t.paa); + (_dlgVector displayCtrl IDC_DIGIT_3) ctrlSetText QPATHTOF(rsc\vector_t.paa); + (_dlgVector displayCtrl IDC_DIGIT_4) ctrlSetText ""; }; case ("nigt"): { - (_dlgVector displayCtrl 1315) ctrlSetText ""; - (_dlgVector displayCtrl 1316) ctrlSetText QPATHTOF(rsc\vector_n.paa); - (_dlgVector displayCtrl 1317) ctrlSetText QPATHTOF(rsc\vector_i.paa); - (_dlgVector displayCtrl 1318) ctrlSetText QPATHTOF(rsc\vector_g.paa); - (_dlgVector displayCtrl 1319) ctrlSetText QPATHTOF(rsc\vector_t.paa); + (_dlgVector displayCtrl IDC_DIGIT_5) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_6) ctrlSetText QPATHTOF(rsc\vector_n.paa); + (_dlgVector displayCtrl IDC_DIGIT_7) ctrlSetText QPATHTOF(rsc\vector_i.paa); + (_dlgVector displayCtrl IDC_DIGIT_8) ctrlSetText QPATHTOF(rsc\vector_g.paa); + (_dlgVector displayCtrl IDC_DIGIT_9) ctrlSetText QPATHTOF(rsc\vector_t.paa); }; case ("eret"): { - (_dlgVector displayCtrl 1315) ctrlSetText ""; - (_dlgVector displayCtrl 1316) ctrlSetText QPATHTOF(rsc\vector_e.paa); - (_dlgVector displayCtrl 1317) ctrlSetText QPATHTOF(rsc\vector_r.paa); - (_dlgVector displayCtrl 1318) ctrlSetText QPATHTOF(rsc\vector_e.paa); - (_dlgVector displayCtrl 1319) ctrlSetText QPATHTOF(rsc\vector_t.paa); + (_dlgVector displayCtrl IDC_DIGIT_5) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_6) ctrlSetText QPATHTOF(rsc\vector_e.paa); + (_dlgVector displayCtrl IDC_DIGIT_7) ctrlSetText QPATHTOF(rsc\vector_r.paa); + (_dlgVector displayCtrl IDC_DIGIT_8) ctrlSetText QPATHTOF(rsc\vector_e.paa); + (_dlgVector displayCtrl IDC_DIGIT_9) ctrlSetText QPATHTOF(rsc\vector_t.paa); }; case ("on"): { - (_dlgVector displayCtrl 1310) ctrlSetText QPATHTOF(rsc\vector_o.paa); - (_dlgVector displayCtrl 1311) ctrlSetText QPATHTOF(rsc\vector_n.paa); - (_dlgVector displayCtrl 1312) ctrlSetText ""; - (_dlgVector displayCtrl 1313) ctrlSetText ""; - (_dlgVector displayCtrl 1314) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_0) ctrlSetText QPATHTOF(rsc\vector_o.paa); + (_dlgVector displayCtrl IDC_DIGIT_1) ctrlSetText QPATHTOF(rsc\vector_n.paa); + (_dlgVector displayCtrl IDC_DIGIT_2) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_3) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_4) ctrlSetText ""; }; case ("off"): { - (_dlgVector displayCtrl 1310) ctrlSetText QPATHTOF(rsc\vector_o.paa); - (_dlgVector displayCtrl 1311) ctrlSetText QPATHTOF(rsc\vector_f.paa); - (_dlgVector displayCtrl 1312) ctrlSetText QPATHTOF(rsc\vector_f.paa); - (_dlgVector displayCtrl 1313) ctrlSetText ""; - (_dlgVector displayCtrl 1314) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_0) ctrlSetText QPATHTOF(rsc\vector_o.paa); + (_dlgVector displayCtrl IDC_DIGIT_1) ctrlSetText QPATHTOF(rsc\vector_f.paa); + (_dlgVector displayCtrl IDC_DIGIT_2) ctrlSetText QPATHTOF(rsc\vector_f.paa); + (_dlgVector displayCtrl IDC_DIGIT_3) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_4) ctrlSetText ""; }; case ("deg"): { - (_dlgVector displayCtrl 1315) ctrlSetText ""; - (_dlgVector displayCtrl 1316) ctrlSetText QPATHTOF(rsc\vector_3.paa); - (_dlgVector displayCtrl 1317) ctrlSetText QPATHTOF(rsc\vector_6.paa); - (_dlgVector displayCtrl 1318) ctrlSetText QPATHTOF(rsc\vector_0.paa); - (_dlgVector displayCtrl 1319) ctrlSetText QPATHTOF(rsc\vector_degree.paa); + (_dlgVector displayCtrl IDC_DIGIT_5) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_6) ctrlSetText QPATHTOF(rsc\vector_3.paa); + (_dlgVector displayCtrl IDC_DIGIT_7) ctrlSetText QPATHTOF(rsc\vector_6.paa); + (_dlgVector displayCtrl IDC_DIGIT_8) ctrlSetText QPATHTOF(rsc\vector_0.paa); + (_dlgVector displayCtrl IDC_DIGIT_9) ctrlSetText QPATHTOF(rsc\vector_degree.paa); }; case ("mil"): { - (_dlgVector displayCtrl 1315) ctrlSetText ""; - (_dlgVector displayCtrl 1316) ctrlSetText QPATHTOF(rsc\vector_6.paa); - (_dlgVector displayCtrl 1317) ctrlSetText QPATHTOF(rsc\vector_4.paa); - (_dlgVector displayCtrl 1318) ctrlSetText QPATHTOF(rsc\vector_0.paa); - (_dlgVector displayCtrl 1319) ctrlSetText QPATHTOF(rsc\vector_0.paa); + (_dlgVector displayCtrl IDC_DIGIT_5) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_6) ctrlSetText QPATHTOF(rsc\vector_6.paa); + (_dlgVector displayCtrl IDC_DIGIT_7) ctrlSetText QPATHTOF(rsc\vector_4.paa); + (_dlgVector displayCtrl IDC_DIGIT_8) ctrlSetText QPATHTOF(rsc\vector_0.paa); + (_dlgVector displayCtrl IDC_DIGIT_9) ctrlSetText QPATHTOF(rsc\vector_0.paa); }; case ("meter"): { - (_dlgVector displayCtrl 1310) ctrlSetText QPATHTOF(rsc\vector_5.paa); - (_dlgVector displayCtrl 1311) ctrlSetText QPATHTOF(rsc\vector_1.paa); - (_dlgVector displayCtrl 1312) ctrlSetText QPATHTOF(rsc\vector_minus.paa); - (_dlgVector displayCtrl 1313) ctrlSetText QPATHTOF(rsc\vector_u.paa); - (_dlgVector displayCtrl 1314) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_0) ctrlSetText QPATHTOF(rsc\vector_5.paa); + (_dlgVector displayCtrl IDC_DIGIT_1) ctrlSetText QPATHTOF(rsc\vector_1.paa); + (_dlgVector displayCtrl IDC_DIGIT_2) ctrlSetText QPATHTOF(rsc\vector_minus.paa); + (_dlgVector displayCtrl IDC_DIGIT_3) ctrlSetText QPATHTOF(rsc\vector_u.paa); + (_dlgVector displayCtrl IDC_DIGIT_4) ctrlSetText ""; }; case ("feet"): { - (_dlgVector displayCtrl 1310) ctrlSetText QPATHTOF(rsc\vector_f.paa); - (_dlgVector displayCtrl 1311) ctrlSetText QPATHTOF(rsc\vector_e.paa); - (_dlgVector displayCtrl 1312) ctrlSetText QPATHTOF(rsc\vector_e.paa); - (_dlgVector displayCtrl 1313) ctrlSetText QPATHTOF(rsc\vector_t.paa); - (_dlgVector displayCtrl 1314) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_0) ctrlSetText QPATHTOF(rsc\vector_f.paa); + (_dlgVector displayCtrl IDC_DIGIT_1) ctrlSetText QPATHTOF(rsc\vector_e.paa); + (_dlgVector displayCtrl IDC_DIGIT_2) ctrlSetText QPATHTOF(rsc\vector_e.paa); + (_dlgVector displayCtrl IDC_DIGIT_3) ctrlSetText QPATHTOF(rsc\vector_t.paa); + (_dlgVector displayCtrl IDC_DIGIT_4) ctrlSetText ""; }; case ("stor"): { - (_dlgVector displayCtrl 1321) ctrlSetText QPATHTOF(rsc\vector_5.paa); - (_dlgVector displayCtrl 1322) ctrlSetText QPATHTOF(rsc\vector_t.paa); - (_dlgVector displayCtrl 1323) ctrlSetText QPATHTOF(rsc\vector_o.paa); - (_dlgVector displayCtrl 1324) ctrlSetText QPATHTOF(rsc\vector_r.paa); + (_dlgVector displayCtrl IDC_DIGIT_E1) ctrlSetText QPATHTOF(rsc\vector_5.paa); + (_dlgVector displayCtrl IDC_DIGIT_E2) ctrlSetText QPATHTOF(rsc\vector_t.paa); + (_dlgVector displayCtrl IDC_DIGIT_E3) ctrlSetText QPATHTOF(rsc\vector_o.paa); + (_dlgVector displayCtrl IDC_DIGIT_E4) ctrlSetText QPATHTOF(rsc\vector_r.paa); }; case ("old_config"): { - (_dlgVector displayCtrl 1315) ctrlSetText ""; - (_dlgVector displayCtrl 1316) ctrlSetText ""; - (_dlgVector displayCtrl 1317) ctrlSetText QPATHTOF(rsc\vector_o.paa); - (_dlgVector displayCtrl 1318) ctrlSetText QPATHTOF(rsc\vector_1.paa); - (_dlgVector displayCtrl 1319) ctrlSetText QPATHTOF(rsc\vector_d.paa); - (_dlgVector displayCtrl 1310) ctrlSetText QPATHTOF(rsc\vector_c.paa); - (_dlgVector displayCtrl 1311) ctrlSetText QPATHTOF(rsc\vector_o.paa); - (_dlgVector displayCtrl 1312) ctrlSetText QPATHTOF(rsc\vector_n.paa); - (_dlgVector displayCtrl 1313) ctrlSetText QPATHTOF(rsc\vector_f.paa); - (_dlgVector displayCtrl 1314) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_5) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_6) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_7) ctrlSetText QPATHTOF(rsc\vector_o.paa); + (_dlgVector displayCtrl IDC_DIGIT_8) ctrlSetText QPATHTOF(rsc\vector_1.paa); + (_dlgVector displayCtrl IDC_DIGIT_9) ctrlSetText QPATHTOF(rsc\vector_d.paa); + (_dlgVector displayCtrl IDC_DIGIT_0) ctrlSetText QPATHTOF(rsc\vector_c.paa); + (_dlgVector displayCtrl IDC_DIGIT_1) ctrlSetText QPATHTOF(rsc\vector_o.paa); + (_dlgVector displayCtrl IDC_DIGIT_2) ctrlSetText QPATHTOF(rsc\vector_n.paa); + (_dlgVector displayCtrl IDC_DIGIT_3) ctrlSetText QPATHTOF(rsc\vector_f.paa); + (_dlgVector displayCtrl IDC_DIGIT_4) ctrlSetText ""; }; case ("old_settings"): { - (_dlgVector displayCtrl 1315) ctrlSetText ""; - (_dlgVector displayCtrl 1316) ctrlSetText ""; - (_dlgVector displayCtrl 1317) ctrlSetText QPATHTOF(rsc\vector_o.paa); - (_dlgVector displayCtrl 1318) ctrlSetText QPATHTOF(rsc\vector_1.paa); - (_dlgVector displayCtrl 1319) ctrlSetText QPATHTOF(rsc\vector_d.paa); - (_dlgVector displayCtrl 1310) ctrlSetText QPATHTOF(rsc\vector_u.paa); - (_dlgVector displayCtrl 1311) ctrlSetText QPATHTOF(rsc\vector_n.paa); - (_dlgVector displayCtrl 1312) ctrlSetText QPATHTOF(rsc\vector_i.paa); - (_dlgVector displayCtrl 1313) ctrlSetText QPATHTOF(rsc\vector_t.paa); - (_dlgVector displayCtrl 1314) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_5) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_6) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_7) ctrlSetText QPATHTOF(rsc\vector_o.paa); + (_dlgVector displayCtrl IDC_DIGIT_8) ctrlSetText QPATHTOF(rsc\vector_1.paa); + (_dlgVector displayCtrl IDC_DIGIT_9) ctrlSetText QPATHTOF(rsc\vector_d.paa); + (_dlgVector displayCtrl IDC_DIGIT_0) ctrlSetText QPATHTOF(rsc\vector_u.paa); + (_dlgVector displayCtrl IDC_DIGIT_1) ctrlSetText QPATHTOF(rsc\vector_n.paa); + (_dlgVector displayCtrl IDC_DIGIT_2) ctrlSetText QPATHTOF(rsc\vector_i.paa); + (_dlgVector displayCtrl IDC_DIGIT_3) ctrlSetText QPATHTOF(rsc\vector_t.paa); + (_dlgVector displayCtrl IDC_DIGIT_4) ctrlSetText ""; }; case ("clear_left"): { - (_dlgVector displayCtrl 1315) ctrlSetText ""; - (_dlgVector displayCtrl 1316) ctrlSetText ""; - (_dlgVector displayCtrl 1317) ctrlSetText ""; - (_dlgVector displayCtrl 1318) ctrlSetText ""; - (_dlgVector displayCtrl 1319) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_5) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_6) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_7) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_8) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_9) ctrlSetText ""; }; case ("clear_right"): { - (_dlgVector displayCtrl 1310) ctrlSetText ""; - (_dlgVector displayCtrl 1311) ctrlSetText ""; - (_dlgVector displayCtrl 1312) ctrlSetText ""; - (_dlgVector displayCtrl 1313) ctrlSetText ""; - (_dlgVector displayCtrl 1314) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_0) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_1) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_2) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_3) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_4) ctrlSetText ""; }; case ("clear_stor"): { - (_dlgVector displayCtrl 1321) ctrlSetText ""; - (_dlgVector displayCtrl 1322) ctrlSetText ""; - (_dlgVector displayCtrl 1323) ctrlSetText ""; - (_dlgVector displayCtrl 1324) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_E1) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_E2) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_E3) ctrlSetText ""; + (_dlgVector displayCtrl IDC_DIGIT_E4) ctrlSetText ""; }; }; diff --git a/addons/vector/initKeybinds.sqf b/addons/vector/initKeybinds.sqf index 5b099235da..7d81561993 100644 --- a/addons/vector/initKeybinds.sqf +++ b/addons/vector/initKeybinds.sqf @@ -1,11 +1,8 @@ -// by commy2 - -["ACE3 Equipment", QGVAR(AzimuthKey), localize LSTRING(AzimuthKey), -{ +["ACE3 Equipment", QGVAR(AzimuthKey), localize LSTRING(AzimuthKey), { // Conditions: canInteract if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific - if !(((currentWeapon ACE_player) isKindOf ["ACE_Vector", configFile >> "CfgWeapons"]) && {cameraView == "GUNNER"}) exitWith {false}; + if !(currentWeapon ACE_player isKindOf ["ACE_Vector", configFile >> "CfgWeapons"] && {cameraView == "GUNNER"}) exitWith {false}; // prevent holding down if (GETGVAR(isDownStateKey1,false)) exitWith {false}; @@ -14,8 +11,7 @@ // Statement ["azimuth"] call FUNC(onKeyDown); false -}, -{ +}, { // prevent holding down GVAR(isDownStateKey1) = false; @@ -25,16 +21,13 @@ // Statement ["azimuth"] call FUNC(onKeyUp); false -}, -[15, [false, false, false]], false, 0] call CBA_fnc_addKeybind; //Tab Key +}, [DIK_TAB, [false, false, false]], false, 0] call CBA_fnc_addKeybind; - -["ACE3 Equipment", QGVAR(DistanceKey), localize LSTRING(DistanceKey), -{ +["ACE3 Equipment", QGVAR(DistanceKey), localize LSTRING(DistanceKey), { // Conditions: canInteract if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific - if !(((currentWeapon ACE_player) isKindOf ["ACE_Vector", configFile >> "CfgWeapons"]) && {cameraView == "GUNNER"}) exitWith {false}; + if !(currentWeapon ACE_player isKindOf ["ACE_Vector", configFile >> "CfgWeapons"] && {cameraView == "GUNNER"}) exitWith {false}; // prevent holding down if (GETGVAR(isDownStateKey2,false)) exitWith {false}; @@ -43,8 +36,7 @@ // Statement ["distance"] call FUNC(onKeyDown); false -}, -{ +}, { // prevent holding down GVAR(isDownStateKey2) = false; @@ -54,5 +46,4 @@ // Statement ["distance"] call FUNC(onKeyUp); false -}, -[19, [false, false, false]], false] call CBA_fnc_addKeybind; //R Key +}, [DIK_R, [false, false, false]], false, 0] call CBA_fnc_addKeybind; diff --git a/addons/vector/script_component.hpp b/addons/vector/script_component.hpp index 15787b140f..0c3646f1ff 100644 --- a/addons/vector/script_component.hpp +++ b/addons/vector/script_component.hpp @@ -15,3 +15,31 @@ #endif #include "\z\ace\addons\main\script_macros.hpp" + +#include "\a3\ui_f\hpp\defineDIKCodes.inc" + +#define IDC_CENTER 1301 +#define IDC_CROSSHAIR 1302 + +#define IDC_DIGIT_0 1310 +#define IDC_DIGIT_1 1311 +#define IDC_DIGIT_2 1312 +#define IDC_DIGIT_3 1313 +#define IDC_DIGIT_4 1314 +#define IDC_DIGIT_5 1315 +#define IDC_DIGIT_6 1316 +#define IDC_DIGIT_7 1317 +#define IDC_DIGIT_8 1318 +#define IDC_DIGIT_9 1319 + +#define IDC_DIGIT_E1 1321 +#define IDC_DIGIT_E2 1322 +#define IDC_DIGIT_E3 1323 +#define IDC_DIGIT_E4 1324 + +#define ILLUM_CONTROLS [\ + IDC_CENTER, IDC_CROSSHAIR,\ + IDC_DIGIT_0, IDC_DIGIT_1, IDC_DIGIT_2, IDC_DIGIT_3, IDC_DIGIT_4,\ + IDC_DIGIT_5, IDC_DIGIT_6, IDC_DIGIT_7, IDC_DIGIT_8, IDC_DIGIT_9,\ + IDC_DIGIT_E1, IDC_DIGIT_E2, IDC_DIGIT_E3, IDC_DIGIT_E4\ +] diff --git a/addons/vehiclelock/stringtable.xml b/addons/vehiclelock/stringtable.xml index 738e490454..d84cb63b3a 100644 --- a/addons/vehiclelock/stringtable.xml +++ b/addons/vehiclelock/stringtable.xml @@ -10,6 +10,8 @@ ACE 차량 잠금 ACE Fahrzeugsperre ACE Zamknięcie Pojazdu + ACE Блокировка транспорта + ACE Trancar Veículos Unlock Vehicle diff --git a/addons/vehicles/stringtable.xml b/addons/vehicles/stringtable.xml index 7b6e5d8e57..dbfab45635 100644 --- a/addons/vehicles/stringtable.xml +++ b/addons/vehicles/stringtable.xml @@ -35,9 +35,12 @@ Speed Limit + Geschwindigkeitsbegrenzung Limite di velocità 速度制限 Ograniczenie prędkości + Ограничение скорости + Limite de Velocidade Speed Limiter @@ -46,7 +49,7 @@ Ogranicznik prędkości Omezovač rychlosti Limiteur de vitesse - Ограничение скорости + Ограничитель скорости Sebességkorlátozó Limitador de Velocidade Limitatore di Velocità @@ -57,33 +60,51 @@ Increase Speed Limit + Maximale Geschwindigkeit erhöhen Aumenta limite di velocità 速度制限を増やす Zwiększ ograniczenie prędkości + Увеличить ограничение скорости + Aumentar Limite de Velocidade Decrease Speed Limit + Maximale Geschwindigkeit verringern Diminuisce limite di velocità 速度制限を減らす Zmniejsz ograniczenie prędkości + Уменьшить ограничение скорости + Diminuir Limite de Velocidade Disable automatic engine shut-off Motor nach Verlassen laufen lassen + エンジン自動停止を無効化 + Убрать автовыключение двигателя + Desativar desligamento automático do motor Prevent the automatic shut-off of the engine when exiting vehicles. Verhindere das automatische Abschalten des Motors beim Verlassen des Fahrzeugs. + 車両から降りた時のエンジンの自動停止を防ぎます。 + Запрещает автоматическое выключение двигателя при выходе из транспорта + Previne que o motor do veículo seja desligado automaticamente quando o motorista sair. Hide Eject Action Abspringen-Aktion verstecken Ukryj akcję Wyskocz + Убрать действие 'Выпрыгнуть' + 脱出アクションを非表示 + Ocultar opção de Ejetar Hides the Eject entry from the action menu. Requires a game restart. 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. diff --git a/addons/viewdistance/functions/fnc_changeViewDistance.sqf b/addons/viewdistance/functions/fnc_changeViewDistance.sqf index 40d07cf100..cb8a07db2d 100644 --- a/addons/viewdistance/functions/fnc_changeViewDistance.sqf +++ b/addons/viewdistance/functions/fnc_changeViewDistance.sqf @@ -29,9 +29,11 @@ if (_objectViewDistanceCoeff isEqualType 0) then { if (_objectViewDistanceCoeff > 0) then { setObjectViewDistance (_objectViewDistanceCoeff * viewDistance); } else { - // Restore correct view distance when changing from FoV Based to Off - // Restoring directly inside PFH's self-exit resulted in the need of selecting another option to take effect - setObjectViewDistance GVAR(fovBasedPFHminimalViewDistance); + if (!isNil QGVAR(fovBasedPFHminimalViewDistance)) then { + // Restore correct view distance when changing from FoV Based to Off + // Restoring directly inside PFH's self-exit resulted in the need of selecting another option to take effect + setObjectViewDistance GVAR(fovBasedPFHminimalViewDistance); + }; }; } else { if (isNil QGVAR(fovBasedPFHminimalViewDistance)) then { diff --git a/addons/weaponselect/stringtable.xml b/addons/weaponselect/stringtable.xml index 5148114b0f..72fcd715bc 100644 --- a/addons/weaponselect/stringtable.xml +++ b/addons/weaponselect/stringtable.xml @@ -371,12 +371,15 @@ Toggle Collision Lights + Kollisionslichter an/ausschalten Attiva Luci di Collisione 충돌 표시등 토글 切換碰撞燈 切换碰撞灯 衝突防止灯を切り替え Przełącz światła kolizyjne + Вкл/Выкл Бортовые огни + Alternar Luzes de Colisão diff --git a/addons/weather/stringtable.xml b/addons/weather/stringtable.xml index c5cf4d4a37..5207c9e2fe 100644 --- a/addons/weather/stringtable.xml +++ b/addons/weather/stringtable.xml @@ -90,6 +90,8 @@ 気温や湿度、大気圧によって既存の天候を拡張します。 온도, 습도 및 기압에 따라 기존 날씨를 확장합니다. Poszerza istniejącą pogodę o temperaturę, wilgotność i ciśnienie powietrza. + Расширяет текущие возможности погоды с учетом температуры, влажности и давления + Expande o clima existente com temperatura, humidade e pressão do ar. Update Interval @@ -132,6 +134,8 @@ 風シミュレーション (マップを基に) 바람 시뮬레이션 (지도 기반) Symulacja Wiatru (bazowana na mapie) + Симуляция ветра (на основе местности) + Simulação de Vento (baseado no mapa) Enables the map based wind simulation (overwrites vanilla wind) @@ -142,6 +146,8 @@ マップを基にした風シミュレーションを有効化 (標準の風を上書き) 지도 기반의 바람 시뮬레이션을 활성화합니다 (바닐라 바람을 덮음) Aktywuje symulację wiatru bazującą na mapie (nadpisuje wind z domyślnej wersji gry) + Включает симуляцию ветра на основе текущей местности (переписывает ванильный ветер) + Ativar a simulação de vento dos mapas. (sobrepõe vento vanilla) diff --git a/addons/zeus/functions/fnc_moduleHeal.sqf b/addons/zeus/functions/fnc_moduleHeal.sqf index 287a84ac79..627c48ef36 100644 --- a/addons/zeus/functions/fnc_moduleHeal.sqf +++ b/addons/zeus/functions/fnc_moduleHeal.sqf @@ -45,7 +45,7 @@ switch (false) do { // Heal validated target if (["ace_medical"] call EFUNC(common,isModLoaded)) then { TRACE_1("healing with ace_medical",_unit); - [QEGVAR(medical_treatment,treatmentFullHealLocal), [_unit], _unit] call CBA_fnc_targetEvent; + [QEGVAR(medical_treatment,fullHealLocal), [_unit], _unit] call CBA_fnc_targetEvent; } else { // BI's scripted revive system if ((missionNamespace getVariable ["bis_revive_mode", 0]) != 0) then { diff --git a/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf b/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf index afcacc0c25..fa3ced078c 100644 --- a/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf +++ b/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf @@ -40,9 +40,9 @@ if !(["ACE_Medical"] call EFUNC(common,isModLoaded)) then { if (GETVAR(_unit,EGVAR(captives,isHandcuffed),false)) then { [LSTRING(OnlyNonCaptive)] call FUNC(showMessage); } else { - private _medicN = GETVAR(_unit,EGVAR(medical,medicClass),0); - if (_medicN < 1) then { - _unit setVariable [QEGVAR(medical,medicClass), 1, true]; + private _medicN = GETVAR(_unit,EGVAR(medical,isMedicalVehicle),false); + if !(_medicN) then { + _unit setVariable [QEGVAR(medical,isMedicalVehicle), true, true]; }; }; }; diff --git a/addons/zeus/stringtable.xml b/addons/zeus/stringtable.xml index 0df5016f7d..695407e436 100644 --- a/addons/zeus/stringtable.xml +++ b/addons/zeus/stringtable.xml @@ -6,9 +6,12 @@ Zeus 宙斯 宙斯 + Zeus Zeus 제우스 Zeus + Зевс + Zeus Zeus Settings @@ -262,6 +265,7 @@ Difendi Area 防御区域 防禦區域 + Defender Área Update Editable Objects @@ -273,20 +277,28 @@ Aggiorna Oggetti Modificabili 更新可编辑的物件 更新可編輯的物件 + Обновить редактируемые объекты + Atualizar objetos editáveis Editing Mode 編輯模式 Modalità per editare + Bearbeitungsmodus 編集モード Tryb Edytowania + Режим редактирования + Modo de edição Add or remove editable objects from Zeus 新增或移除可編輯物件給宙斯 + Aktiviere oder deaktiviere zu bearbeitende Objekte von Zeus Agguingi o rimuovi oggetti che Zeus può modificare Zeus から編集可能オブジェクトの追加と削除をする Dodaj lub usuń edytowalne obiekty z Zeus'a + Добавить или удалить редактируемые объекты от Зевса + Adiciona ou remove objetos editáveis do Zeus Add Objects @@ -294,6 +306,8 @@ Aggiungi Oggetti オブジェクト追加 Dodaj obiekty + Добавить объекты + Adicionar Objetos Remove Objects @@ -305,6 +319,8 @@ Rimuovi Oggetti 移除物件 移除物件 + Удалить объекты + Remover Objetos All Curators @@ -316,6 +332,8 @@ Tutti i Moderatori 所有编辑者 所有編輯者 + Все кураторы + Todos os Curadores Apply changes to all curators @@ -327,18 +345,26 @@ Applica i cambiamenti a tutti i moderatori 确认变更给所有编辑者 確認變更給所有編輯者 + Применить изменения ко всем кураторам + Aplicar mudanças à todos os Curadores Additional Objects + Zusätzliche Objekte Oggetti aggiuntivi オブジェクト増加 Dodatkowe obiekty + Доп. объекты + Objetos adicionais 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à タスク範囲に関係無くオブジェクトを更に増加させます 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 Global AI Skill @@ -352,6 +378,7 @@ Abilità AI Globale AI技巧设定 AI技巧設定 + Habilidade Global da IA General Skill @@ -365,6 +392,7 @@ Abilità Generale 总体技巧 總體技巧 + Habilidade Geral Changes: general, commanding, courage @@ -378,6 +406,7 @@ Cambia: generale, comando, 改变: 战斗技巧,指挥技巧,勇气大小 改變: 戰鬥技巧,指揮技巧,勇氣大小 + Muda: general, commanding, courage Accuracy @@ -391,6 +420,7 @@ Precisione 精确度 精確度 + Precisão Changes: aimingAccuracy @@ -404,6 +434,7 @@ Cambia: aimingAccuracy 改变: 瞄准精确度 改變: 瞄準精確度 + Muda: aimingAccuracy Weapon Handling @@ -417,6 +448,7 @@ Uso dell'Arma 武器掌握 武器掌握 + Uso de Arma Changes: aimingShake, aimingSpeed, reloadSpeed @@ -430,6 +462,7 @@ Cambia: aimingShake, aimingSpeed, reloadSpeed 改变: 手晃幅度,瞄准速度, 重新装填速度 改變: 手晃幅度,瞄準速度, 重新裝填速度 + Muda: aimingShake, aimingSpeed, reloadSpeed Spotting @@ -443,6 +476,7 @@ Ricognizione 索敌能力 索敵能力 + Detecção Changes: spotDistance, spotTime @@ -456,6 +490,7 @@ Cambia: spotDistance, spotTime 改变: 搜索距离, 发现时间 改變: 搜索距離, 發現時間 + Muda: spotDistance, spotTime Seek Cover @@ -469,6 +504,7 @@ Cerca Copertura 寻找掩护 尋找掩護 + Procurar Cobertura Should AI seek cover @@ -482,6 +518,7 @@ Le AI dovrebbero cercare una copertura 决定AI是否会寻找掩护 決定AI是否會尋找掩護 + A IA dever buscar cobertura Auto Combat @@ -495,6 +532,7 @@ Combattimento Automatico 自动交战 自動交戰 + Combate automático Should AI automatically switch to combat mode @@ -508,6 +546,7 @@ Le AI dovrebbero passare in modalità di combattimento automaticamente 决定AI是否会自动与敌人交战 決定AI是否會自動與敵人交戰 + A IA deveria automaticamente mudar para modo de combate Group Side @@ -521,6 +560,7 @@ Fazione del Gruppo 小队阵营 小隊陣營 + Lado do Grupo Patrol Area @@ -534,6 +574,7 @@ Area di Pattugliamento 巡逻区域 巡邏區域 + Patrulhar Área Toggle Surrender @@ -561,6 +602,8 @@ Aggiungi/Rimuovi FRIES 增加/移除快速垂降进场撤离系统 增加/移除快速垂降進場撤離系統 + Добавить/Удалить FRIES + Adicionar/Remover FRIES %1 is not fastrope compatible. @@ -572,6 +615,8 @@ %1 non è compatibile con il fastrope. %1无法使用快速绳降系统 %1無法使用快速繩降系統 + %1 несовместим с быстрым спуском + %1 não é compatível com sistema de corda. Unable to remove FRIES, ropes are deployed. @@ -583,6 +628,8 @@ Impossibile rimuovere le FRIES, le corde sono ancora dispiegate 无法移除快速绳降系统,因为绳索已被释放出来 無法移除快速繩降系統,因為繩索已被釋放出來 + Невозможно удалить FRIES, канаты развернуты. + Não foi possível remover o FRIES, as cordas estão soltas. Teleport Players @@ -596,6 +643,7 @@ Teletrasporta Giocatori 传送玩家 傳送玩家 + Teleportar Jogadores Player @@ -609,6 +657,7 @@ Giocatore 玩家 玩家 + Jogador Teleport selected player to module position @@ -622,6 +671,7 @@ Teletrasporta il giocatore selezionato nella posizione del modulo 传送选定的玩家至模块位置 傳送選定的玩家至模塊位置 + Teleporta o jogador selecionado para a posição do módulo Teleport Group @@ -635,6 +685,7 @@ Teletrasporta Gruppo 传送小队 傳送小隊 + Teleportar Grupo Teleports all units in group @@ -648,6 +699,7 @@ Teletrasporta tutte le unità del gruppo 传送全部小队成员 傳送全部小隊成員 + Teleporta todas as unidades do grupo Toggle Unconscious @@ -677,6 +729,7 @@ Area di Ricerca 搜索区域 搜索區域 + Procurar Área Search Nearby Building @@ -690,6 +743,7 @@ Cerca Edifici nelle Vicinanze 搜索附近的建筑物 搜索附近的建築物 + Procurar construções próximas Assign Medic @@ -746,10 +800,12 @@ Attivatore Simulazione 切换模拟 切換模擬 + Вкл/Выкл симуляцию + Alternar Simulação Add Spare Wheel - Adicionar roda sobressalente + Adicionar roda sobressalente (estepe) Dodaj koło zapasowe Добавить запасное колесо Přidat rezervní kolo @@ -787,7 +843,7 @@ Применимо только к живым юнитам Csak élő egységeken használni Si può fare solo su persone vive - Usar somente em unidades vivas + Unidade deve estar viva ユニットを生存させます 대상이 반드시 살아있어야 합니다 单位必须是活着 @@ -803,7 +859,7 @@ Применимо только к пехоте вне техники Csak járműben kívül lévő egységeken használni Si può usare solo su fanteria a piedi - Usar somente em infantaria desmontada + Unidade deve ser uma infantaria desmontada ユニットを歩兵にさせます 대상이 반드시 보병이어야 합니다 单位必须是步兵 @@ -856,7 +912,7 @@ Unit must have cargo space left - Unidade deve conter espaço sobressalente + Unidade deve conter espaço sobressalente de carga Jednostka musi mieć wolną przestrzeń cargo Юнит должен иметь свободное место в грузовом отсеке Jednotka musí mít místo v úložném prostoru @@ -897,6 +953,7 @@ L'unità deve appartenere ad una fazione coerente 单位必须属于一个合适的一边 單位必須屬於一個合適的一邊 + Unidade deve pertencer á um lado apropriado Nearest building is too far away @@ -910,6 +967,7 @@ L'edificio più vicino è troppo lontano 最近的房子离太远了 最近的房子離太遠了 + A construção mais próxima está longe demais Place on a unit @@ -945,21 +1003,30 @@ None + Keiner Niente Żadne なし + Нет + Nenhum Players + Spieler Giocatori Gracze プレイヤー + Игроки + Jogadores Players and AI + Spieler und KI's Giocati e AI Gracze i SI プレイヤーと AI + Игроки и ИИ + Jogadores e IA Add Objects to Curator @@ -1003,13 +1070,17 @@ Cargo: 货物: 貨物: + Carga: Select cargo to unload + Ladung zum ausladen auswählen 選擇要卸載的貨物 Scegli il carico da scaricare 選択したカーゴを降ろす Wybierz ładunek do wyładowania + Выберите груз для выгрузки + Selecione objeto para descarregar Task Radius @@ -1022,6 +1093,7 @@ Raggio Incarico 目标半径 目標半徑 + Área da tarefa Radius to perform the task within @@ -1034,6 +1106,7 @@ Raggio per eseguire un incarico 设定目标范围半径 設定目標範圍半徑 + Raio para se executar uma tarefa Invalid radius entered @@ -1047,6 +1120,7 @@ Raggio Invalido Inserito 错误的半径值 錯誤的半徑值 + Raio inválido inserido Suppressive Fire @@ -1058,6 +1132,8 @@ 火力壓制 Ogień zaporowy 엄호사격 + Огонь на подавление + Fogo de Supressão Add Full Arsenal @@ -1069,6 +1145,8 @@ 增加完整的虛擬軍火庫到物件上 Dodaj Wirtualny Arsenał 아스날 놓기 + Добавить весь Арсенал + Adicionar Arsenal Completo Remove Arsenal @@ -1080,6 +1158,8 @@ 移除物件上的虛擬軍火庫 Usuń Wirtualny Arsenał 아스날 제거 + Убрать Арсенал + Remover Arsenal Load into Cargo @@ -1090,6 +1170,8 @@ 装载到货物中 화물 싣기 Załaduj do ładunku + Загрузить в отсек + Carregar na carga Toggle NVGs @@ -1101,6 +1183,8 @@ 切换夜视镜 야시경 토글 Przełącz NVG + Вкл/Выкл ПНВ + Alternar Visão Noturna NVG Equipment @@ -1112,6 +1196,8 @@ 夜视镜装备 야시경 장비 Ekwipunek NVG + Приборы ночного видения + Equipamento de Visão Noturna Add or remove NVGs from units @@ -1123,22 +1209,30 @@ 增加或移除单位的夜视镜 야시경 추가/제거 Dodaj lub usuń noktowizję z jednostek + Добавить/Убрать ПНВ у юнитов + Adiciona ou remove visão noturna de unidades Toggle Target + Ziel umschalten 目標を切り替え 切换目标 切換目標 Scambia obiettivo Przełącz cel + Кому переключить + Alternar alvo Units affected by the toggle + Betroffene Spieler beim umschalten ユニットは切り替えに影響を受けます 被选单位受切换影响 受切換所影響的單位 Unità influenzate dallo scambio Jednostki pod wpływem przełączenia + Юниты, к которым применяется переключение + Unidades afetadas pela alteração Selected Group @@ -1150,6 +1244,8 @@ 选择小队 그룹 선택 Wybrana grupa + Выбранная группа + Grupo Selecionado Toggle Flashlights @@ -1161,6 +1257,8 @@ 切换手电筒 손전등 토글 Przełącz latarki + Вкл/Выкл Фонари + Alternar Lanternas Flashlights @@ -1172,6 +1270,8 @@ 手电筒 손전등 Latarki + Фонари + Lanternas Add Gear @@ -1183,9 +1283,12 @@ 增加装备 장비 추가 Dodaj wyposażenie + Добавить снаряжение + Adicionar equipamento Garrison Group + Gebäude besetzen Garnir zone 歩哨グループ Proteggi gruppo @@ -1193,9 +1296,12 @@ 布置驻军 그룹 주둔 Rozmieść grupę w garnizonie + Разместить группу в здании + Guarnecer grupo Fill from top to bottom + Von oben nach unten befüllen Remplir de haut en bas 上から下まで占拠 Riempi dall'alto al basso @@ -1203,9 +1309,12 @@ 由上而下进行填满 위에서부터 채우기 Wypełnij od góry do dołu + Занять здание сверху до низу + Preencher de cima para baixo Fill buildings from the highest position first + Gebäude von der höchsten Position zuerst befüllen Remplir les bâtiments par la position la plus haute d'abord 建物を最も高い位置から占拠していきます Riempi gli edifici dalla posizione più alta prima @@ -1213,9 +1322,12 @@ 从建筑物的最高点开始布置卫哨 건물의 높은 위치부터 먼저 채움 Wypełnij budynki zaczynając od najwyższej pozycji + Занять здание начиная с верхних позиций + Preencher construções do lugar mais alto primeiro Building filling mode + Gebäude befüllen Mode de remplissage de bâtiment 建物占拠モード Modalità riempimento edifici @@ -1223,9 +1335,12 @@ 驻军填充建筑物模式 건물 채우기 모드 Tryb wypełniania budynków + Режим заполнения здания + Modo de preenchimento da construção Even filling + Gleichmäßig befüllen Remplissage égal 均一に占拠 Riempimento uguale @@ -1233,9 +1348,12 @@ 平均分配 평균 채우기 Równe wypełnienie + Равномерно + Preenchimento equilibrado Building by building + Gebäude nach Gebäude Bâtiment par bâtiment 建物から建物へ Edificio per edificio @@ -1243,9 +1361,12 @@ 一栋填满后再换下一栋 건물에서 건물로 Budynek za budynkiem + Здание за зданием + Construção por construção Random filling + Zufällig füllen Remplir au hasard ランダムに占拠 Riempimento casuale @@ -1253,9 +1374,12 @@ 随机分配 무작위 채우기 Losowe wypełnienie + Случайно + Preenchimento aleatório Teleport + Teleportieren Téléporter テレポート Teletrasporto @@ -1263,9 +1387,12 @@ 传送 순간이동 Teleport + Телепорт + Teleportar Un-garrison Group + Garnisionsgruppe auflösen Dégarnir zone 非歩哨グループ Non proteggere gruppo @@ -1273,6 +1400,8 @@ 解除驻军驻守状态 주둔해제 Cofnij rozmieszczenie grupu w garnizonie + Вывести группу из здания + Desguarnecer grupo No players found @@ -1302,7 +1431,7 @@ 修理車両を割り当てる 수리 차량 지정 Przydziel pojazd do naprawy - Atribuir veículo de reparação + Definir como veículo de reparo Назначить ремонтный автомобиль Asignar vehículo de reparación @@ -1318,7 +1447,7 @@ 修理施設を割り当てる 수리 시설 지정 Przydziel naprawę - Atribuir facilidade de reparação + Definir como oficina de reparo Назначить ремонтный комплекс Asignar instalación de reparación @@ -1334,7 +1463,7 @@ 担当エンジニア 엔지니어 지정 Przydziel inżyniera - Encarregar o engenheiro + Definir como engenheiro Назначить инженера Asignar Ingeniero @@ -1398,7 +1527,7 @@ 対象陣営 활성화면 Strona aktywacji - Lado de ativação + Explodir em: Сторона активации Lado de activación @@ -1414,7 +1543,7 @@ 活性化半径 활성화 반경 Promień aktywacji - Rádio de ativação + Raio de ativação Радиус активации Radio de activación @@ -1446,7 +1575,7 @@ 自動誘導 자동 탐색 Auto Seek - Busca automática + Buscar alvos automaticamente Автоматический поиск Búsqueda automática @@ -1484,50 +1613,68 @@ Add full ACE Arsenal + Vollständiges ACE Arsenal hinzufügen ACE 武器庫を追加 添加ACE模式军火库 增加完整的ACE軍火庫 Aggiungi l'arsenale ACE completo Dodaj pełny arsenał ACE + Добавить полный ACE Арсенал + Adicionar Arsenal ACE Completo Remove ACE Arsenal + ACE Arsenal entfernen ACE 武器庫を削除 删除ACE模式军火库 移除ACE軍火庫 Rimuovi l'arsenale ACE Usuń arsenał ACE + Убрать ACE Арсенал + Remover Arsenal ACE Create Zeus + Zeus erstellen Создать Зевса Zeus を作る Stwórz Zeus'a Crea Zeus + Criar Zeus Delete Zeus + Zeus löschen Удалить Зевса Zeus を消す Usuń Zeus'a Cancella Zeus + Apagar Zeus "%1" menu + "%1" Menü Меню "%1" "%1" メニュー "%1" menu menu "%1" + Menu "%1" Paradrop Cargo + Paradrop Ladung カーゴを空中投下 Zrzut ładunku (cargo) + Десантировать груз + Soltar carga de paraquedas No cargo loaded + Keine Ladung geladen カーゴは未積載 Niczego nie załadowano do cargo + Грузовой отсек пуст + Nenhuma carga carregada diff --git a/circle.yml b/circle.yml deleted file mode 100644 index 5cd5f0d72d..0000000000 --- a/circle.yml +++ /dev/null @@ -1,63 +0,0 @@ -version: 2 -jobs: - validate-scripts: - docker: - - image: acemod/sqflint:latest - steps: - - checkout - - run: - name: Validate SQF and Config style and Stringtable entries - command: python tools/sqf_validator.py && python tools/config_style_checker.py && python tools/check_strings.py - - linting: - docker: - - image: acemod/sqflint:latest - steps: - - checkout - - run: - name: Lint sqf code - command: sqflint -d addons || true - - armake: - docker: - - image: acemod/armake:master - steps: - - checkout - - run: - name: Version - command: armake --version - - run: - name: Build - command: | - make -j 4 - - update-docs: - docker: - - image: acemod/armake:latest - steps: - - checkout - - run: - name: Update documentation and translation statistics - command: | - if [ "${CIRCLE_BRANCH}" == "master" ] && [ "${CIRCLE_PROJECT_USERNAME}" == "acemod" ]; then - pip install pygithub pygithub3 - python3 tools/deploy.py - else - echo "Skipping, not on acemod/ACE3 master branch..." - fi - -workflows: - version: 2 - build-job: - jobs: - - linting - - validate-scripts - - armake: - requires: - - validate-scripts - - update-docs: - requires: - - armake - filters: - branches: - only: master diff --git a/docs/_includes/dependencies_list.md b/docs/_includes/dependencies_list.md index c3ce51ec82..d601eda8df 100644 --- a/docs/_includes/dependencies_list.md +++ b/docs/_includes/dependencies_list.md @@ -66,6 +66,10 @@ `ace_common` {% endif %} +{% if include.component == "csw" %} +`ace_interaction` +{% endif %} + {% if include.component == "dagr" %} `ace_weather` {% endif %} @@ -86,6 +90,10 @@ `ace_interaction` {% endif %} +{% if include.component == "dragon" %} +`ace_hot`, `ace_csw` +{% endif %} + {% if include.component == "explosives" %} `ace_interaction` {% endif %} @@ -279,7 +287,7 @@ {% endif %} {% if include.component == "mk6mortar" %} -`ace_interaction` +`ace_csw` {% endif %} {% if include.component == "modules" %} @@ -499,15 +507,15 @@ {% endif %} {% if include.component == "compat_rhs_afrf3" %} -`ace_rearm`, `ace_refuel`, `ace_repair`, `rhs_c_weapons`, `rhs_c_troops`, `rhs_c_bmd`, `rhs_c_bmp`, `rhs_c_bmp3`, `rhs_c_a2port_armor`, `rhs_c_btr`, `rhs_c_sprut`, `rhs_c_t72`, `rhs_c_tanks`, `rhs_c_a2port_air`, `rhs_c_a2port_car`, `rhs_c_cars`, `rhs_c_trucks`, `rhs_c_2s3`, `rhs_c_rva`, `rhs_c_heavyweapons` +`ace_csw`, `ace_rearm`, `ace_refuel`, `ace_repair`, `rhs_c_weapons`, `rhs_c_troops`, `rhs_c_bmd`, `rhs_c_bmp`, `rhs_c_bmp3`, `rhs_c_a2port_armor`, `rhs_c_btr`, `rhs_c_sprut`, `rhs_c_t72`, `rhs_c_tanks`, `rhs_c_a2port_air`, `rhs_c_a2port_car`, `rhs_c_cars`, `rhs_c_trucks`, `rhs_c_2s3`, `rhs_c_rva`, `rhs_c_heavyweapons` {% endif %} {% if include.component == "compat_rhs_gref3" %} -`rhsgref_main`, `rhsgref_c_weapons` +`ace_csw`, `rhsgref_main`, `rhsgref_c_weapons` {% endif %} {% if include.component == "compat_rhs_usf3" %} -`ace_javelin`, `ace_rearm`, `ace_refuel`, `ace_repair`, `rhsusf_c_weapons`, `rhsusf_c_troops`, `rhsusf_c_m1a1`, `rhsusf_c_m1a2`, `RHS_US_A2_AirImport`, `rhsusf_c_m109`, `rhsusf_c_HEMTT_A4`, `rhsusf_c_hmmwv`, `rhsusf_c_rg33`, `rhsusf_c_fmtv`, `rhsusf_c_m113`, `RHS_US_A2Port_Armor`, `rhsusf_c_melb` +`ace_explosives`, `ace_javelin`, `ace_rearm`, `ace_refuel`, `ace_repair`, `ace_csw`, `rhsusf_c_weapons`, `rhsusf_c_troops`, `rhsusf_c_m1a1`, `rhsusf_c_m1a2`, `RHS_US_A2_AirImport`, `rhsusf_c_m109`, `rhsusf_c_HEMTT_A4`, `rhsusf_c_hmmwv`, `rhsusf_c_rg33`, `rhsusf_c_fmtv`, `rhsusf_c_m113`, `RHS_US_A2Port_Armor`, `rhsusf_c_melb` {% endif %} {% if include.component == "compat_rksl_pm_ii" %} diff --git a/docs/css/app.css b/docs/css/app.css index 8130470b22..505903a5d0 100644 --- a/docs/css/app.css +++ b/docs/css/app.css @@ -1,4 +1,4 @@ -/*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}meta.foundation-version{font-family:"/5.5.1/"}meta.foundation-mq-small{font-family:"/only screen/";width:0em}meta.foundation-mq-small-only{font-family:"/only screen and (max-width: 40em)/";width:0em}meta.foundation-mq-medium{font-family:"/only screen and (min-width:40.0625em)/";width:40.0625em}meta.foundation-mq-medium-only{font-family:"/only screen and (min-width:40.0625em) and (max-width:64em)/";width:40.0625em}meta.foundation-mq-large{font-family:"/only screen and (min-width:64.0625em)/";width:64.0625em}meta.foundation-mq-large-only{font-family:"/only screen and (min-width:64.0625em) and (max-width:90em)/";width:64.0625em}meta.foundation-mq-xlarge{font-family:"/only screen and (min-width:90.0625em)/";width:90.0625em}meta.foundation-mq-xlarge-only{font-family:"/only screen and (min-width:90.0625em) and (max-width:120em)/";width:90.0625em}meta.foundation-mq-xxlarge{font-family:"/only screen and (min-width:120.0625em)/";width:120.0625em}meta.foundation-data-attribute-namespace{font-family:false}html,body{height:100%}*,*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html,body{font-size:100%}body{background:#fff;color:#222;padding:0;margin:0;font-family:"Open Sans","Helvetica Neue",Helvetica,Roboto,Arial,sans-serif;font-weight:400;font-style:normal;line-height:1.5;position:relative;cursor:auto}a:hover{cursor:pointer}img{max-width:100%;height:auto}img{-ms-interpolation-mode:bicubic}#map_canvas img,#map_canvas embed,#map_canvas object,.map_canvas img,.map_canvas embed,.map_canvas object{max-width:none !important}.left{float:left !important}.right{float:right !important}.clearfix:before,.clearfix:after{content:" ";display:table}.clearfix:after{clear:both}.hide{display:none}.invisible{visibility:hidden}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}img{display:inline-block;vertical-align:middle}textarea{height:auto;min-height:50px}select{width:100%}[class*="block-grid-"]{display:block;padding:0;margin:0 -.625rem}[class*="block-grid-"]:before,[class*="block-grid-"]:after{content:" ";display:table}[class*="block-grid-"]:after{clear:both}[class*="block-grid-"]>li{display:block;height:auto;float:left;padding:0 .625rem 1.25rem}@media only screen{.small-block-grid-1>li{width:100%;list-style:none}.small-block-grid-1>li:nth-of-type(1n){clear:none}.small-block-grid-1>li:nth-of-type(1n+1){clear:both}.small-block-grid-2>li{width:50%;list-style:none}.small-block-grid-2>li:nth-of-type(1n){clear:none}.small-block-grid-2>li:nth-of-type(2n+1){clear:both}.small-block-grid-3>li{width:33.3333333333%;list-style:none}.small-block-grid-3>li:nth-of-type(1n){clear:none}.small-block-grid-3>li:nth-of-type(3n+1){clear:both}.small-block-grid-4>li{width:25%;list-style:none}.small-block-grid-4>li:nth-of-type(1n){clear:none}.small-block-grid-4>li:nth-of-type(4n+1){clear:both}.small-block-grid-5>li{width:20%;list-style:none}.small-block-grid-5>li:nth-of-type(1n){clear:none}.small-block-grid-5>li:nth-of-type(5n+1){clear:both}.small-block-grid-6>li{width:16.6666666667%;list-style:none}.small-block-grid-6>li:nth-of-type(1n){clear:none}.small-block-grid-6>li:nth-of-type(6n+1){clear:both}.small-block-grid-7>li{width:14.2857142857%;list-style:none}.small-block-grid-7>li:nth-of-type(1n){clear:none}.small-block-grid-7>li:nth-of-type(7n+1){clear:both}.small-block-grid-8>li{width:12.5%;list-style:none}.small-block-grid-8>li:nth-of-type(1n){clear:none}.small-block-grid-8>li:nth-of-type(8n+1){clear:both}.small-block-grid-9>li{width:11.1111111111%;list-style:none}.small-block-grid-9>li:nth-of-type(1n){clear:none}.small-block-grid-9>li:nth-of-type(9n+1){clear:both}.small-block-grid-10>li{width:10%;list-style:none}.small-block-grid-10>li:nth-of-type(1n){clear:none}.small-block-grid-10>li:nth-of-type(10n+1){clear:both}.small-block-grid-11>li{width:9.0909090909%;list-style:none}.small-block-grid-11>li:nth-of-type(1n){clear:none}.small-block-grid-11>li:nth-of-type(11n+1){clear:both}.small-block-grid-12>li{width:8.3333333333%;list-style:none}.small-block-grid-12>li:nth-of-type(1n){clear:none}.small-block-grid-12>li:nth-of-type(12n+1){clear:both}}@media only screen and (min-width: 40.0625em){.medium-block-grid-1>li{width:100%;list-style:none}.medium-block-grid-1>li:nth-of-type(1n){clear:none}.medium-block-grid-1>li:nth-of-type(1n+1){clear:both}.medium-block-grid-2>li{width:50%;list-style:none}.medium-block-grid-2>li:nth-of-type(1n){clear:none}.medium-block-grid-2>li:nth-of-type(2n+1){clear:both}.medium-block-grid-3>li{width:33.3333333333%;list-style:none}.medium-block-grid-3>li:nth-of-type(1n){clear:none}.medium-block-grid-3>li:nth-of-type(3n+1){clear:both}.medium-block-grid-4>li{width:25%;list-style:none}.medium-block-grid-4>li:nth-of-type(1n){clear:none}.medium-block-grid-4>li:nth-of-type(4n+1){clear:both}.medium-block-grid-5>li{width:20%;list-style:none}.medium-block-grid-5>li:nth-of-type(1n){clear:none}.medium-block-grid-5>li:nth-of-type(5n+1){clear:both}.medium-block-grid-6>li{width:16.6666666667%;list-style:none}.medium-block-grid-6>li:nth-of-type(1n){clear:none}.medium-block-grid-6>li:nth-of-type(6n+1){clear:both}.medium-block-grid-7>li{width:14.2857142857%;list-style:none}.medium-block-grid-7>li:nth-of-type(1n){clear:none}.medium-block-grid-7>li:nth-of-type(7n+1){clear:both}.medium-block-grid-8>li{width:12.5%;list-style:none}.medium-block-grid-8>li:nth-of-type(1n){clear:none}.medium-block-grid-8>li:nth-of-type(8n+1){clear:both}.medium-block-grid-9>li{width:11.1111111111%;list-style:none}.medium-block-grid-9>li:nth-of-type(1n){clear:none}.medium-block-grid-9>li:nth-of-type(9n+1){clear:both}.medium-block-grid-10>li{width:10%;list-style:none}.medium-block-grid-10>li:nth-of-type(1n){clear:none}.medium-block-grid-10>li:nth-of-type(10n+1){clear:both}.medium-block-grid-11>li{width:9.0909090909%;list-style:none}.medium-block-grid-11>li:nth-of-type(1n){clear:none}.medium-block-grid-11>li:nth-of-type(11n+1){clear:both}.medium-block-grid-12>li{width:8.3333333333%;list-style:none}.medium-block-grid-12>li:nth-of-type(1n){clear:none}.medium-block-grid-12>li:nth-of-type(12n+1){clear:both}}@media only screen and (min-width: 64.0625em){.large-block-grid-1>li{width:100%;list-style:none}.large-block-grid-1>li:nth-of-type(1n){clear:none}.large-block-grid-1>li:nth-of-type(1n+1){clear:both}.large-block-grid-2>li{width:50%;list-style:none}.large-block-grid-2>li:nth-of-type(1n){clear:none}.large-block-grid-2>li:nth-of-type(2n+1){clear:both}.large-block-grid-3>li{width:33.3333333333%;list-style:none}.large-block-grid-3>li:nth-of-type(1n){clear:none}.large-block-grid-3>li:nth-of-type(3n+1){clear:both}.large-block-grid-4>li{width:25%;list-style:none}.large-block-grid-4>li:nth-of-type(1n){clear:none}.large-block-grid-4>li:nth-of-type(4n+1){clear:both}.large-block-grid-5>li{width:20%;list-style:none}.large-block-grid-5>li:nth-of-type(1n){clear:none}.large-block-grid-5>li:nth-of-type(5n+1){clear:both}.large-block-grid-6>li{width:16.6666666667%;list-style:none}.large-block-grid-6>li:nth-of-type(1n){clear:none}.large-block-grid-6>li:nth-of-type(6n+1){clear:both}.large-block-grid-7>li{width:14.2857142857%;list-style:none}.large-block-grid-7>li:nth-of-type(1n){clear:none}.large-block-grid-7>li:nth-of-type(7n+1){clear:both}.large-block-grid-8>li{width:12.5%;list-style:none}.large-block-grid-8>li:nth-of-type(1n){clear:none}.large-block-grid-8>li:nth-of-type(8n+1){clear:both}.large-block-grid-9>li{width:11.1111111111%;list-style:none}.large-block-grid-9>li:nth-of-type(1n){clear:none}.large-block-grid-9>li:nth-of-type(9n+1){clear:both}.large-block-grid-10>li{width:10%;list-style:none}.large-block-grid-10>li:nth-of-type(1n){clear:none}.large-block-grid-10>li:nth-of-type(10n+1){clear:both}.large-block-grid-11>li{width:9.0909090909%;list-style:none}.large-block-grid-11>li:nth-of-type(1n){clear:none}.large-block-grid-11>li:nth-of-type(11n+1){clear:both}.large-block-grid-12>li{width:8.3333333333%;list-style:none}.large-block-grid-12>li:nth-of-type(1n){clear:none}.large-block-grid-12>li:nth-of-type(12n+1){clear:both}}button,.button{border-style:solid;border-width:0;cursor:pointer;font-family:"Open Sans","Helvetica Neue",Helvetica,Roboto,Arial,sans-serif;font-weight:400;line-height:normal;margin:0 0 1.25rem;position:relative;text-decoration:none;text-align:center;-webkit-appearance:none;-moz-appearance:none;border-radius:0;display:inline-block;padding-top:1rem;padding-right:2rem;padding-bottom:1.0625rem;padding-left:2rem;font-size:1rem;background-color:#ba2619;border-color:#951e14;color:#fff;transition:background-color 300ms ease-out}button:hover,button:focus,.button:hover,.button:focus{background-color:#951e14}button:hover,button:focus,.button:hover,.button:focus{color:#fff}button.secondary,.button.secondary{background-color:#e7e7e7;border-color:#b9b9b9;color:#333}button.secondary:hover,button.secondary:focus,.button.secondary:hover,.button.secondary:focus{background-color:#b9b9b9}button.secondary:hover,button.secondary:focus,.button.secondary:hover,.button.secondary:focus{color:#333}button.success,.button.success{background-color:#43AC6A;border-color:#368a55;color:#fff}button.success:hover,button.success:focus,.button.success:hover,.button.success:focus{background-color:#368a55}button.success:hover,button.success:focus,.button.success:hover,.button.success:focus{color:#fff}button.alert,.button.alert{background-color:#f04124;border-color:#cf2a0e;color:#fff}button.alert:hover,button.alert:focus,.button.alert:hover,.button.alert:focus{background-color:#cf2a0e}button.alert:hover,button.alert:focus,.button.alert:hover,.button.alert:focus{color:#fff}button.warning,.button.warning{background-color:#f08a24;border-color:#cf6e0e;color:#fff}button.warning:hover,button.warning:focus,.button.warning:hover,.button.warning:focus{background-color:#cf6e0e}button.warning:hover,button.warning:focus,.button.warning:hover,.button.warning:focus{color:#fff}button.info,.button.info{background-color:#a0d3e8;border-color:#61b6d9;color:#333}button.info:hover,button.info:focus,.button.info:hover,.button.info:focus{background-color:#61b6d9}button.info:hover,button.info:focus,.button.info:hover,.button.info:focus{color:#fff}button.large,.button.large{padding-top:1.125rem;padding-right:2.25rem;padding-bottom:1.1875rem;padding-left:2.25rem;font-size:1.25rem}button.small,.button.small{padding-top:.875rem;padding-right:1.75rem;padding-bottom:.9375rem;padding-left:1.75rem;font-size:.8125rem}button.tiny,.button.tiny{padding-top:.625rem;padding-right:1.25rem;padding-bottom:.6875rem;padding-left:1.25rem;font-size:.6875rem}button.expand,.button.expand{padding-right:0;padding-left:0;width:100%}button.left-align,.button.left-align{text-align:left;text-indent:.75rem}button.right-align,.button.right-align{text-align:right;padding-right:.75rem}button.radius,.button.radius{border-radius:3px}button.round,.button.round{border-radius:1000px}button.disabled,button[disabled],.button.disabled,.button[disabled]{background-color:#ba2619;border-color:#951e14;color:#fff;cursor:default;opacity:.7;box-shadow:none}button.disabled:hover,button.disabled:focus,button[disabled]:hover,button[disabled]:focus,.button.disabled:hover,.button.disabled:focus,.button[disabled]:hover,.button[disabled]:focus{background-color:#951e14}button.disabled:hover,button.disabled:focus,button[disabled]:hover,button[disabled]:focus,.button.disabled:hover,.button.disabled:focus,.button[disabled]:hover,.button[disabled]:focus{color:#fff}button.disabled:hover,button.disabled:focus,button[disabled]:hover,button[disabled]:focus,.button.disabled:hover,.button.disabled:focus,.button[disabled]:hover,.button[disabled]:focus{background-color:#ba2619}button.disabled.secondary,button[disabled].secondary,.button.disabled.secondary,.button[disabled].secondary{background-color:#e7e7e7;border-color:#b9b9b9;color:#333;cursor:default;opacity:.7;box-shadow:none}button.disabled.secondary:hover,button.disabled.secondary:focus,button[disabled].secondary:hover,button[disabled].secondary:focus,.button.disabled.secondary:hover,.button.disabled.secondary:focus,.button[disabled].secondary:hover,.button[disabled].secondary:focus{background-color:#b9b9b9}button.disabled.secondary:hover,button.disabled.secondary:focus,button[disabled].secondary:hover,button[disabled].secondary:focus,.button.disabled.secondary:hover,.button.disabled.secondary:focus,.button[disabled].secondary:hover,.button[disabled].secondary:focus{color:#333}button.disabled.secondary:hover,button.disabled.secondary:focus,button[disabled].secondary:hover,button[disabled].secondary:focus,.button.disabled.secondary:hover,.button.disabled.secondary:focus,.button[disabled].secondary:hover,.button[disabled].secondary:focus{background-color:#e7e7e7}button.disabled.success,button[disabled].success,.button.disabled.success,.button[disabled].success{background-color:#43AC6A;border-color:#368a55;color:#fff;cursor:default;opacity:.7;box-shadow:none}button.disabled.success:hover,button.disabled.success:focus,button[disabled].success:hover,button[disabled].success:focus,.button.disabled.success:hover,.button.disabled.success:focus,.button[disabled].success:hover,.button[disabled].success:focus{background-color:#368a55}button.disabled.success:hover,button.disabled.success:focus,button[disabled].success:hover,button[disabled].success:focus,.button.disabled.success:hover,.button.disabled.success:focus,.button[disabled].success:hover,.button[disabled].success:focus{color:#fff}button.disabled.success:hover,button.disabled.success:focus,button[disabled].success:hover,button[disabled].success:focus,.button.disabled.success:hover,.button.disabled.success:focus,.button[disabled].success:hover,.button[disabled].success:focus{background-color:#43AC6A}button.disabled.alert,button[disabled].alert,.button.disabled.alert,.button[disabled].alert{background-color:#f04124;border-color:#cf2a0e;color:#fff;cursor:default;opacity:.7;box-shadow:none}button.disabled.alert:hover,button.disabled.alert:focus,button[disabled].alert:hover,button[disabled].alert:focus,.button.disabled.alert:hover,.button.disabled.alert:focus,.button[disabled].alert:hover,.button[disabled].alert:focus{background-color:#cf2a0e}button.disabled.alert:hover,button.disabled.alert:focus,button[disabled].alert:hover,button[disabled].alert:focus,.button.disabled.alert:hover,.button.disabled.alert:focus,.button[disabled].alert:hover,.button[disabled].alert:focus{color:#fff}button.disabled.alert:hover,button.disabled.alert:focus,button[disabled].alert:hover,button[disabled].alert:focus,.button.disabled.alert:hover,.button.disabled.alert:focus,.button[disabled].alert:hover,.button[disabled].alert:focus{background-color:#f04124}button.disabled.warning,button[disabled].warning,.button.disabled.warning,.button[disabled].warning{background-color:#f08a24;border-color:#cf6e0e;color:#fff;cursor:default;opacity:.7;box-shadow:none}button.disabled.warning:hover,button.disabled.warning:focus,button[disabled].warning:hover,button[disabled].warning:focus,.button.disabled.warning:hover,.button.disabled.warning:focus,.button[disabled].warning:hover,.button[disabled].warning:focus{background-color:#cf6e0e}button.disabled.warning:hover,button.disabled.warning:focus,button[disabled].warning:hover,button[disabled].warning:focus,.button.disabled.warning:hover,.button.disabled.warning:focus,.button[disabled].warning:hover,.button[disabled].warning:focus{color:#fff}button.disabled.warning:hover,button.disabled.warning:focus,button[disabled].warning:hover,button[disabled].warning:focus,.button.disabled.warning:hover,.button.disabled.warning:focus,.button[disabled].warning:hover,.button[disabled].warning:focus{background-color:#f08a24}button.disabled.info,button[disabled].info,.button.disabled.info,.button[disabled].info{background-color:#a0d3e8;border-color:#61b6d9;color:#333;cursor:default;opacity:.7;box-shadow:none}button.disabled.info:hover,button.disabled.info:focus,button[disabled].info:hover,button[disabled].info:focus,.button.disabled.info:hover,.button.disabled.info:focus,.button[disabled].info:hover,.button[disabled].info:focus{background-color:#61b6d9}button.disabled.info:hover,button.disabled.info:focus,button[disabled].info:hover,button[disabled].info:focus,.button.disabled.info:hover,.button.disabled.info:focus,.button[disabled].info:hover,.button[disabled].info:focus{color:#fff}button.disabled.info:hover,button.disabled.info:focus,button[disabled].info:hover,button[disabled].info:focus,.button.disabled.info:hover,.button.disabled.info:focus,.button[disabled].info:hover,.button[disabled].info:focus{background-color:#a0d3e8}button::-moz-focus-inner{border:0;padding:0}@media only screen and (min-width: 40.0625em){button,.button{display:inline-block}}.clearing-thumbs,[data-clearing]{margin-bottom:0;margin-left:0;list-style:none}.clearing-thumbs:before,.clearing-thumbs:after,[data-clearing]:before,[data-clearing]:after{content:" ";display:table}.clearing-thumbs:after,[data-clearing]:after{clear:both}.clearing-thumbs li,[data-clearing] li{float:left;margin-right:10px}.clearing-thumbs[class*="block-grid-"] li,[data-clearing][class*="block-grid-"] li{margin-right:0}.clearing-blackout{background:#333;position:fixed;width:100%;height:100%;top:0;left:0;z-index:998}.clearing-blackout .clearing-close{display:block}.clearing-container{position:relative;z-index:998;height:100%;overflow:hidden;margin:0}.clearing-touch-label{position:absolute;top:50%;left:50%;color:#aaa;font-size:0.6em}.visible-img{height:95%;position:relative}.visible-img img{position:absolute;left:50%;top:50%;transform:translateY(-50%) translateX(-50%);-webkit-transform:translateY(-50%) translateX(-50%);-ms-transform:translateY(-50%) translateX(-50%);max-height:100%;max-width:100%}.clearing-caption{color:#ccc;font-size:.875em;line-height:1.3;margin-bottom:0;text-align:center;bottom:0;background:#333;width:100%;padding:10px 30px 20px;position:absolute;left:0}.clearing-close{z-index:999;padding-left:20px;padding-top:10px;font-size:30px;line-height:1;color:#ccc;display:none}.clearing-close:hover,.clearing-close:focus{color:#ccc}.clearing-assembled .clearing-container{height:100%}.clearing-assembled .clearing-container .carousel>ul{display:none}.clearing-feature li{display:none}.clearing-feature li.clearing-featured-img{display:block}@media only screen and (min-width: 40.0625em){.clearing-main-prev,.clearing-main-next{position:absolute;height:100%;width:40px;top:0}.clearing-main-prev>span,.clearing-main-next>span{position:absolute;top:50%;display:block;width:0;height:0;border:solid 12px}.clearing-main-prev>span:hover,.clearing-main-next>span:hover{opacity:0.8}.clearing-main-prev{left:0}.clearing-main-prev>span{left:5px;border-color:transparent;border-right-color:#ccc}.clearing-main-next{right:0}.clearing-main-next>span{border-color:transparent;border-left-color:#ccc}.clearing-main-prev.disabled,.clearing-main-next.disabled{opacity:0.3}.clearing-assembled .clearing-container .carousel{background:rgba(51,51,51,0.8);height:120px;margin-top:10px;text-align:center}.clearing-assembled .clearing-container .carousel>ul{display:inline-block;z-index:999;height:100%;position:relative;float:none}.clearing-assembled .clearing-container .carousel>ul li{display:block;width:120px;min-height:inherit;float:left;overflow:hidden;margin-right:0;padding:0;position:relative;cursor:pointer;opacity:0.4;clear:none}.clearing-assembled .clearing-container .carousel>ul li.fix-height img{height:100%;max-width:none}.clearing-assembled .clearing-container .carousel>ul li a.th{border:none;box-shadow:none;display:block}.clearing-assembled .clearing-container .carousel>ul li img{cursor:pointer !important;width:100% !important}.clearing-assembled .clearing-container .carousel>ul li.visible{opacity:1}.clearing-assembled .clearing-container .carousel>ul li:hover{opacity:0.8}.clearing-assembled .clearing-container .visible-img{background:#333;overflow:hidden;height:85%}.clearing-close{position:absolute;top:10px;right:20px;padding-left:0;padding-top:0}}form{margin:0 0 1rem}form .row .row{margin:0 -.5rem}form .row .row .column,form .row .row .columns{padding:0 .5rem}form .row .row.collapse{margin:0}form .row .row.collapse .column,form .row .row.collapse .columns{padding:0}form .row .row.collapse input{-webkit-border-bottom-right-radius:0;-webkit-border-top-right-radius:0;border-bottom-right-radius:0;border-top-right-radius:0}form .row input.column,form .row input.columns,form .row textarea.column,form .row textarea.columns{padding-left:.5rem}label{font-size:.875rem;color:#4d4c4c;cursor:pointer;display:block;font-weight:400;line-height:1.5;margin-bottom:0}label.right{float:none !important;text-align:right}label.inline{margin:0 0 1rem 0;padding:.5625rem 0}label small{text-transform:capitalize;color:#676767}.prefix,.postfix{display:block;position:relative;z-index:2;text-align:center;width:100%;padding-top:0;padding-bottom:0;border-style:solid;border-width:1px;overflow:visible;font-size:.875rem;height:2.3125rem;line-height:2.3125rem}.postfix.button{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;text-align:center;border:none}.prefix.button{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;text-align:center;border:none}.prefix.button.radius{border-radius:0;-webkit-border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-bottom-left-radius:3px;border-top-left-radius:3px}.postfix.button.radius{border-radius:0;-webkit-border-bottom-right-radius:3px;-webkit-border-top-right-radius:3px;border-bottom-right-radius:3px;border-top-right-radius:3px}.prefix.button.round{border-radius:0;-webkit-border-bottom-left-radius:1000px;-webkit-border-top-left-radius:1000px;border-bottom-left-radius:1000px;border-top-left-radius:1000px}.postfix.button.round{border-radius:0;-webkit-border-bottom-right-radius:1000px;-webkit-border-top-right-radius:1000px;border-bottom-right-radius:1000px;border-top-right-radius:1000px}span.prefix,label.prefix{background:#f2f2f2;border-right:none;color:#333;border-color:#ccc}span.postfix,label.postfix{background:#f2f2f2;border-left:none;color:#333;border-color:#ccc}input[type="text"],input[type="password"],input[type="date"],input[type="datetime"],input[type="datetime-local"],input[type="month"],input[type="week"],input[type="email"],input[type="number"],input[type="search"],input[type="tel"],input[type="time"],input[type="url"],input[type="color"],textarea{-webkit-appearance:none;border-radius:0;background-color:#fff;font-family:inherit;border-style:solid;border-width:1px;border-color:#ccc;box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);color:rgba(0,0,0,0.75);display:block;font-size:.875rem;margin:0 0 1rem 0;padding:.5rem;height:2.3125rem;width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;transition:all .15s linear}input[type="text"]:focus,input[type="password"]:focus,input[type="date"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="month"]:focus,input[type="week"]:focus,input[type="email"]:focus,input[type="number"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="time"]:focus,input[type="url"]:focus,input[type="color"]:focus,textarea:focus{background:#fafafa;border-color:#999;outline:none}input[type="text"]:disabled,input[type="password"]:disabled,input[type="date"]:disabled,input[type="datetime"]:disabled,input[type="datetime-local"]:disabled,input[type="month"]:disabled,input[type="week"]:disabled,input[type="email"]:disabled,input[type="number"]:disabled,input[type="search"]:disabled,input[type="tel"]:disabled,input[type="time"]:disabled,input[type="url"]:disabled,input[type="color"]:disabled,textarea:disabled{background-color:#ddd;cursor:default}input[type="text"][disabled],input[type="text"][readonly],fieldset[disabled] input[type="text"],input[type="password"][disabled],input[type="password"][readonly],fieldset[disabled] input[type="password"],input[type="date"][disabled],input[type="date"][readonly],fieldset[disabled] input[type="date"],input[type="datetime"][disabled],input[type="datetime"][readonly],fieldset[disabled] input[type="datetime"],input[type="datetime-local"][disabled],input[type="datetime-local"][readonly],fieldset[disabled] input[type="datetime-local"],input[type="month"][disabled],input[type="month"][readonly],fieldset[disabled] input[type="month"],input[type="week"][disabled],input[type="week"][readonly],fieldset[disabled] input[type="week"],input[type="email"][disabled],input[type="email"][readonly],fieldset[disabled] input[type="email"],input[type="number"][disabled],input[type="number"][readonly],fieldset[disabled] input[type="number"],input[type="search"][disabled],input[type="search"][readonly],fieldset[disabled] input[type="search"],input[type="tel"][disabled],input[type="tel"][readonly],fieldset[disabled] input[type="tel"],input[type="time"][disabled],input[type="time"][readonly],fieldset[disabled] input[type="time"],input[type="url"][disabled],input[type="url"][readonly],fieldset[disabled] input[type="url"],input[type="color"][disabled],input[type="color"][readonly],fieldset[disabled] input[type="color"],textarea[disabled],textarea[readonly],fieldset[disabled] textarea{background-color:#ddd;cursor:default}input[type="text"].radius,input[type="password"].radius,input[type="date"].radius,input[type="datetime"].radius,input[type="datetime-local"].radius,input[type="month"].radius,input[type="week"].radius,input[type="email"].radius,input[type="number"].radius,input[type="search"].radius,input[type="tel"].radius,input[type="time"].radius,input[type="url"].radius,input[type="color"].radius,textarea.radius{border-radius:3px}form .row .prefix-radius.row.collapse input,form .row .prefix-radius.row.collapse textarea,form .row .prefix-radius.row.collapse select,form .row .prefix-radius.row.collapse button{border-radius:0;-webkit-border-bottom-right-radius:3px;-webkit-border-top-right-radius:3px;border-bottom-right-radius:3px;border-top-right-radius:3px}form .row .prefix-radius.row.collapse .prefix{border-radius:0;-webkit-border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-bottom-left-radius:3px;border-top-left-radius:3px}form .row .postfix-radius.row.collapse input,form .row .postfix-radius.row.collapse textarea,form .row .postfix-radius.row.collapse select,form .row .postfix-radius.row.collapse button{border-radius:0;-webkit-border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-bottom-left-radius:3px;border-top-left-radius:3px}form .row .postfix-radius.row.collapse .postfix{border-radius:0;-webkit-border-bottom-right-radius:3px;-webkit-border-top-right-radius:3px;border-bottom-right-radius:3px;border-top-right-radius:3px}form .row .prefix-round.row.collapse input,form .row .prefix-round.row.collapse textarea,form .row .prefix-round.row.collapse select,form .row .prefix-round.row.collapse button{border-radius:0;-webkit-border-bottom-right-radius:1000px;-webkit-border-top-right-radius:1000px;border-bottom-right-radius:1000px;border-top-right-radius:1000px}form .row .prefix-round.row.collapse .prefix{border-radius:0;-webkit-border-bottom-left-radius:1000px;-webkit-border-top-left-radius:1000px;border-bottom-left-radius:1000px;border-top-left-radius:1000px}form .row .postfix-round.row.collapse input,form .row .postfix-round.row.collapse textarea,form .row .postfix-round.row.collapse select,form .row .postfix-round.row.collapse button{border-radius:0;-webkit-border-bottom-left-radius:1000px;-webkit-border-top-left-radius:1000px;border-bottom-left-radius:1000px;border-top-left-radius:1000px}form .row .postfix-round.row.collapse .postfix{border-radius:0;-webkit-border-bottom-right-radius:1000px;-webkit-border-top-right-radius:1000px;border-bottom-right-radius:1000px;border-top-right-radius:1000px}input[type="submit"]{-webkit-appearance:none;border-radius:0}textarea[rows]{height:auto}textarea{max-width:100%}select{-webkit-appearance:none !important;border-radius:0;background-color:#FAFAFA;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgeD0iMTJweCIgeT0iMHB4IiB3aWR0aD0iMjRweCIgaGVpZ2h0PSIzcHgiIHZpZXdCb3g9IjAgMCA2IDMiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDYgMyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBvbHlnb24gcG9pbnRzPSI1Ljk5MiwwIDIuOTkyLDMgLTAuMDA4LDAgIi8+PC9zdmc+);background-position:100% center;background-repeat:no-repeat;border-style:solid;border-width:1px;border-color:#ccc;padding:.5rem;font-size:.875rem;font-family:"Open Sans","Helvetica Neue",Helvetica,Roboto,Arial,sans-serif;color:rgba(0,0,0,0.75);line-height:normal;border-radius:0;height:2.3125rem}select::-ms-expand{display:none}select.radius{border-radius:3px}select:hover{background-color:#f3f2f2;border-color:#999}select:disabled{background-color:#ddd;cursor:default}select[multiple]{height:auto}input[type="file"],input[type="checkbox"],input[type="radio"],select{margin:0 0 1rem 0}input[type="checkbox"]+label,input[type="radio"]+label{display:inline-block;margin-left:.5rem;margin-right:1rem;margin-bottom:0;vertical-align:baseline}input[type="file"]{width:100%}fieldset{border:1px solid #ddd;padding:1.25rem;margin:1.125rem 0}fieldset legend{font-weight:700;background:#fff;padding:0 .1875rem;margin:0;margin-left:-.1875rem}[data-abide] .error small.error,[data-abide] .error span.error,[data-abide] span.error,[data-abide] small.error{display:block;padding:.375rem .5625rem .5625rem;margin-top:-1px;margin-bottom:1rem;font-size:.75rem;font-weight:400;font-style:italic;background:#f04124;color:#fff}[data-abide] span.error,[data-abide] small.error{display:none}span.error,small.error{display:block;padding:.375rem .5625rem .5625rem;margin-top:-1px;margin-bottom:1rem;font-size:.75rem;font-weight:400;font-style:italic;background:#f04124;color:#fff}.error input,.error textarea,.error select{margin-bottom:0}.error input[type="checkbox"],.error input[type="radio"]{margin-bottom:1rem}.error label,.error label.error{color:#f04124}.error small.error{display:block;padding:.375rem .5625rem .5625rem;margin-top:-1px;margin-bottom:1rem;font-size:.75rem;font-weight:400;font-style:italic;background:#f04124;color:#fff}.error>label>small{color:#676767;background:transparent;padding:0;text-transform:capitalize;font-style:normal;font-size:60%;margin:0;display:inline}.error span.error-message{display:block}input.error,textarea.error,select.error{margin-bottom:0}label.error{color:#f04124}.row{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5rem}.row:before,.row:after{content:" ";display:table}.row:after{clear:both}.row.collapse>.column,.row.collapse>.columns{padding-left:0;padding-right:0}.row.collapse .row{margin-left:0;margin-right:0}.row .row{width:auto;margin-left:-.9375rem;margin-right:-.9375rem;margin-top:0;margin-bottom:0;max-width:none}.row .row:before,.row .row:after{content:" ";display:table}.row .row:after{clear:both}.row .row.collapse{width:auto;margin:0;max-width:none}.row .row.collapse:before,.row .row.collapse:after{content:" ";display:table}.row .row.collapse:after{clear:both}.column,.columns{padding-left:.9375rem;padding-right:.9375rem;width:100%;float:left}[class*="column"]+[class*="column"]:last-child{float:right}[class*="column"]+[class*="column"].end{float:left}@media only screen{.small-push-0{position:relative;left:0%;right:auto}.small-pull-0{position:relative;right:0%;left:auto}.small-push-1{position:relative;left:8.3333333333%;right:auto}.small-pull-1{position:relative;right:8.3333333333%;left:auto}.small-push-2{position:relative;left:16.6666666667%;right:auto}.small-pull-2{position:relative;right:16.6666666667%;left:auto}.small-push-3{position:relative;left:25%;right:auto}.small-pull-3{position:relative;right:25%;left:auto}.small-push-4{position:relative;left:33.3333333333%;right:auto}.small-pull-4{position:relative;right:33.3333333333%;left:auto}.small-push-5{position:relative;left:41.6666666667%;right:auto}.small-pull-5{position:relative;right:41.6666666667%;left:auto}.small-push-6{position:relative;left:50%;right:auto}.small-pull-6{position:relative;right:50%;left:auto}.small-push-7{position:relative;left:58.3333333333%;right:auto}.small-pull-7{position:relative;right:58.3333333333%;left:auto}.small-push-8{position:relative;left:66.6666666667%;right:auto}.small-pull-8{position:relative;right:66.6666666667%;left:auto}.small-push-9{position:relative;left:75%;right:auto}.small-pull-9{position:relative;right:75%;left:auto}.small-push-10{position:relative;left:83.3333333333%;right:auto}.small-pull-10{position:relative;right:83.3333333333%;left:auto}.small-push-11{position:relative;left:91.6666666667%;right:auto}.small-pull-11{position:relative;right:91.6666666667%;left:auto}.column,.columns{position:relative;padding-left:.9375rem;padding-right:.9375rem;float:left}.small-1{width:8.3333333333%}.small-2{width:16.6666666667%}.small-3{width:25%}.small-4{width:33.3333333333%}.small-5{width:41.6666666667%}.small-6{width:50%}.small-7{width:58.3333333333%}.small-8{width:66.6666666667%}.small-9{width:75%}.small-10{width:83.3333333333%}.small-11{width:91.6666666667%}.small-12{width:100%}.small-offset-0{margin-left:0% !important}.small-offset-1{margin-left:8.3333333333% !important}.small-offset-2{margin-left:16.6666666667% !important}.small-offset-3{margin-left:25% !important}.small-offset-4{margin-left:33.3333333333% !important}.small-offset-5{margin-left:41.6666666667% !important}.small-offset-6{margin-left:50% !important}.small-offset-7{margin-left:58.3333333333% !important}.small-offset-8{margin-left:66.6666666667% !important}.small-offset-9{margin-left:75% !important}.small-offset-10{margin-left:83.3333333333% !important}.small-offset-11{margin-left:91.6666666667% !important}.small-reset-order{margin-left:0;margin-right:0;left:auto;right:auto;float:left}.column.small-centered,.columns.small-centered{margin-left:auto;margin-right:auto;float:none}.column.small-uncentered,.columns.small-uncentered{margin-left:0;margin-right:0;float:left}.column.small-centered:last-child,.columns.small-centered:last-child{float:none}.column.small-uncentered:last-child,.columns.small-uncentered:last-child{float:left}.column.small-uncentered.opposite,.columns.small-uncentered.opposite{float:right}.row.small-collapse>.column,.row.small-collapse>.columns{padding-left:0;padding-right:0}.row.small-collapse .row{margin-left:0;margin-right:0}.row.small-uncollapse>.column,.row.small-uncollapse>.columns{padding-left:.9375rem;padding-right:.9375rem;float:left}}@media only screen and (min-width: 40.0625em){.medium-push-0{position:relative;left:0%;right:auto}.medium-pull-0{position:relative;right:0%;left:auto}.medium-push-1{position:relative;left:8.3333333333%;right:auto}.medium-pull-1{position:relative;right:8.3333333333%;left:auto}.medium-push-2{position:relative;left:16.6666666667%;right:auto}.medium-pull-2{position:relative;right:16.6666666667%;left:auto}.medium-push-3{position:relative;left:25%;right:auto}.medium-pull-3{position:relative;right:25%;left:auto}.medium-push-4{position:relative;left:33.3333333333%;right:auto}.medium-pull-4{position:relative;right:33.3333333333%;left:auto}.medium-push-5{position:relative;left:41.6666666667%;right:auto}.medium-pull-5{position:relative;right:41.6666666667%;left:auto}.medium-push-6{position:relative;left:50%;right:auto}.medium-pull-6{position:relative;right:50%;left:auto}.medium-push-7{position:relative;left:58.3333333333%;right:auto}.medium-pull-7{position:relative;right:58.3333333333%;left:auto}.medium-push-8{position:relative;left:66.6666666667%;right:auto}.medium-pull-8{position:relative;right:66.6666666667%;left:auto}.medium-push-9{position:relative;left:75%;right:auto}.medium-pull-9{position:relative;right:75%;left:auto}.medium-push-10{position:relative;left:83.3333333333%;right:auto}.medium-pull-10{position:relative;right:83.3333333333%;left:auto}.medium-push-11{position:relative;left:91.6666666667%;right:auto}.medium-pull-11{position:relative;right:91.6666666667%;left:auto}.column,.columns{position:relative;padding-left:.9375rem;padding-right:.9375rem;float:left}.medium-1{width:8.3333333333%}.medium-2{width:16.6666666667%}.medium-3{width:25%}.medium-4{width:33.3333333333%}.medium-5{width:41.6666666667%}.medium-6{width:50%}.medium-7{width:58.3333333333%}.medium-8{width:66.6666666667%}.medium-9{width:75%}.medium-10{width:83.3333333333%}.medium-11{width:91.6666666667%}.medium-12{width:100%}.medium-offset-0{margin-left:0% !important}.medium-offset-1{margin-left:8.3333333333% !important}.medium-offset-2{margin-left:16.6666666667% !important}.medium-offset-3{margin-left:25% !important}.medium-offset-4{margin-left:33.3333333333% !important}.medium-offset-5{margin-left:41.6666666667% !important}.medium-offset-6{margin-left:50% !important}.medium-offset-7{margin-left:58.3333333333% !important}.medium-offset-8{margin-left:66.6666666667% !important}.medium-offset-9{margin-left:75% !important}.medium-offset-10{margin-left:83.3333333333% !important}.medium-offset-11{margin-left:91.6666666667% !important}.medium-reset-order{margin-left:0;margin-right:0;left:auto;right:auto;float:left}.column.medium-centered,.columns.medium-centered{margin-left:auto;margin-right:auto;float:none}.column.medium-uncentered,.columns.medium-uncentered{margin-left:0;margin-right:0;float:left}.column.medium-centered:last-child,.columns.medium-centered:last-child{float:none}.column.medium-uncentered:last-child,.columns.medium-uncentered:last-child{float:left}.column.medium-uncentered.opposite,.columns.medium-uncentered.opposite{float:right}.row.medium-collapse>.column,.row.medium-collapse>.columns{padding-left:0;padding-right:0}.row.medium-collapse .row{margin-left:0;margin-right:0}.row.medium-uncollapse>.column,.row.medium-uncollapse>.columns{padding-left:.9375rem;padding-right:.9375rem;float:left}.push-0{position:relative;left:0%;right:auto}.pull-0{position:relative;right:0%;left:auto}.push-1{position:relative;left:8.3333333333%;right:auto}.pull-1{position:relative;right:8.3333333333%;left:auto}.push-2{position:relative;left:16.6666666667%;right:auto}.pull-2{position:relative;right:16.6666666667%;left:auto}.push-3{position:relative;left:25%;right:auto}.pull-3{position:relative;right:25%;left:auto}.push-4{position:relative;left:33.3333333333%;right:auto}.pull-4{position:relative;right:33.3333333333%;left:auto}.push-5{position:relative;left:41.6666666667%;right:auto}.pull-5{position:relative;right:41.6666666667%;left:auto}.push-6{position:relative;left:50%;right:auto}.pull-6{position:relative;right:50%;left:auto}.push-7{position:relative;left:58.3333333333%;right:auto}.pull-7{position:relative;right:58.3333333333%;left:auto}.push-8{position:relative;left:66.6666666667%;right:auto}.pull-8{position:relative;right:66.6666666667%;left:auto}.push-9{position:relative;left:75%;right:auto}.pull-9{position:relative;right:75%;left:auto}.push-10{position:relative;left:83.3333333333%;right:auto}.pull-10{position:relative;right:83.3333333333%;left:auto}.push-11{position:relative;left:91.6666666667%;right:auto}.pull-11{position:relative;right:91.6666666667%;left:auto}}@media only screen and (min-width: 64.0625em){.large-push-0{position:relative;left:0%;right:auto}.large-pull-0{position:relative;right:0%;left:auto}.large-push-1{position:relative;left:8.3333333333%;right:auto}.large-pull-1{position:relative;right:8.3333333333%;left:auto}.large-push-2{position:relative;left:16.6666666667%;right:auto}.large-pull-2{position:relative;right:16.6666666667%;left:auto}.large-push-3{position:relative;left:25%;right:auto}.large-pull-3{position:relative;right:25%;left:auto}.large-push-4{position:relative;left:33.3333333333%;right:auto}.large-pull-4{position:relative;right:33.3333333333%;left:auto}.large-push-5{position:relative;left:41.6666666667%;right:auto}.large-pull-5{position:relative;right:41.6666666667%;left:auto}.large-push-6{position:relative;left:50%;right:auto}.large-pull-6{position:relative;right:50%;left:auto}.large-push-7{position:relative;left:58.3333333333%;right:auto}.large-pull-7{position:relative;right:58.3333333333%;left:auto}.large-push-8{position:relative;left:66.6666666667%;right:auto}.large-pull-8{position:relative;right:66.6666666667%;left:auto}.large-push-9{position:relative;left:75%;right:auto}.large-pull-9{position:relative;right:75%;left:auto}.large-push-10{position:relative;left:83.3333333333%;right:auto}.large-pull-10{position:relative;right:83.3333333333%;left:auto}.large-push-11{position:relative;left:91.6666666667%;right:auto}.large-pull-11{position:relative;right:91.6666666667%;left:auto}.column,.columns{position:relative;padding-left:.9375rem;padding-right:.9375rem;float:left}.large-1{width:8.3333333333%}.large-2{width:16.6666666667%}.large-3{width:25%}.large-4{width:33.3333333333%}.large-5{width:41.6666666667%}.large-6{width:50%}.large-7{width:58.3333333333%}.large-8{width:66.6666666667%}.large-9{width:75%}.large-10{width:83.3333333333%}.large-11{width:91.6666666667%}.large-12{width:100%}.large-offset-0{margin-left:0% !important}.large-offset-1{margin-left:8.3333333333% !important}.large-offset-2{margin-left:16.6666666667% !important}.large-offset-3{margin-left:25% !important}.large-offset-4{margin-left:33.3333333333% !important}.large-offset-5{margin-left:41.6666666667% !important}.large-offset-6{margin-left:50% !important}.large-offset-7{margin-left:58.3333333333% !important}.large-offset-8{margin-left:66.6666666667% !important}.large-offset-9{margin-left:75% !important}.large-offset-10{margin-left:83.3333333333% !important}.large-offset-11{margin-left:91.6666666667% !important}.large-reset-order{margin-left:0;margin-right:0;left:auto;right:auto;float:left}.column.large-centered,.columns.large-centered{margin-left:auto;margin-right:auto;float:none}.column.large-uncentered,.columns.large-uncentered{margin-left:0;margin-right:0;float:left}.column.large-centered:last-child,.columns.large-centered:last-child{float:none}.column.large-uncentered:last-child,.columns.large-uncentered:last-child{float:left}.column.large-uncentered.opposite,.columns.large-uncentered.opposite{float:right}.row.large-collapse>.column,.row.large-collapse>.columns{padding-left:0;padding-right:0}.row.large-collapse .row{margin-left:0;margin-right:0}.row.large-uncollapse>.column,.row.large-uncollapse>.columns{padding-left:.9375rem;padding-right:.9375rem;float:left}.push-0{position:relative;left:0%;right:auto}.pull-0{position:relative;right:0%;left:auto}.push-1{position:relative;left:8.3333333333%;right:auto}.pull-1{position:relative;right:8.3333333333%;left:auto}.push-2{position:relative;left:16.6666666667%;right:auto}.pull-2{position:relative;right:16.6666666667%;left:auto}.push-3{position:relative;left:25%;right:auto}.pull-3{position:relative;right:25%;left:auto}.push-4{position:relative;left:33.3333333333%;right:auto}.pull-4{position:relative;right:33.3333333333%;left:auto}.push-5{position:relative;left:41.6666666667%;right:auto}.pull-5{position:relative;right:41.6666666667%;left:auto}.push-6{position:relative;left:50%;right:auto}.pull-6{position:relative;right:50%;left:auto}.push-7{position:relative;left:58.3333333333%;right:auto}.pull-7{position:relative;right:58.3333333333%;left:auto}.push-8{position:relative;left:66.6666666667%;right:auto}.pull-8{position:relative;right:66.6666666667%;left:auto}.push-9{position:relative;left:75%;right:auto}.pull-9{position:relative;right:75%;left:auto}.push-10{position:relative;left:83.3333333333%;right:auto}.pull-10{position:relative;right:83.3333333333%;left:auto}.push-11{position:relative;left:91.6666666667%;right:auto}.pull-11{position:relative;right:91.6666666667%;left:auto}}.inline-list{margin:0 auto 1.0625rem auto;margin-left:-1.375rem;margin-right:0;padding:0;list-style:none;overflow:hidden}.inline-list>li{list-style:none;float:left;margin-left:1.375rem;display:block}.inline-list>li>*{display:block}.panel{border-style:solid;border-width:1px;border-color:#d8d8d8;margin-bottom:1.25rem;padding:1.25rem;background:#f2f2f2;color:#333}.panel>:first-child{margin-top:0}.panel>:last-child{margin-bottom:0}.panel h1,.panel h2,.panel h3,.panel h4,.panel h5,.panel h6,.panel p,.panel li,.panel dl{color:#333}.panel h1,.panel h2,.panel h3,.panel h4,.panel h5,.panel h6{line-height:1;margin-bottom:.625rem}.panel h1.subheader,.panel h2.subheader,.panel h3.subheader,.panel h4.subheader,.panel h5.subheader,.panel h6.subheader{line-height:1.4}.panel.callout{border-style:solid;border-width:1px;border-color:#f6c4bf;margin-bottom:1.25rem;padding:1.25rem;background:#fdf0ef;color:#333}.panel.callout>:first-child{margin-top:0}.panel.callout>:last-child{margin-bottom:0}.panel.callout h1,.panel.callout h2,.panel.callout h3,.panel.callout h4,.panel.callout h5,.panel.callout h6,.panel.callout p,.panel.callout li,.panel.callout dl{color:#333}.panel.callout h1,.panel.callout h2,.panel.callout h3,.panel.callout h4,.panel.callout h5,.panel.callout h6{line-height:1;margin-bottom:.625rem}.panel.callout h1.subheader,.panel.callout h2.subheader,.panel.callout h3.subheader,.panel.callout h4.subheader,.panel.callout h5.subheader,.panel.callout h6.subheader{line-height:1.4}.panel.callout a:not(.button){color:#ba2619}.panel.callout a:not(.button):hover,.panel.callout a:not(.button):focus{color:#a02116}.panel.radius{border-radius:3px}.side-nav{display:block;margin:0;padding:.875rem 0;list-style-type:none;list-style-position:outside;font-family:"Open Sans","Helvetica Neue",Helvetica,Roboto,Arial,sans-serif}.side-nav li{margin:0 0 .4375rem 0;font-size:.875rem;font-weight:400}.side-nav li a:not(.button){display:block;color:#ba2619;margin:0;padding:.4375rem .875rem}.side-nav li a:not(.button):hover,.side-nav li a:not(.button):focus{background:rgba(0,0,0,0.025);color:#e65346}.side-nav li.active>a:first-child:not(.button){color:#e65346;font-weight:400;font-family:"Open Sans","Helvetica Neue",Helvetica,Roboto,Arial,sans-serif}.side-nav li.divider{border-top:1px solid;height:0;padding:0;list-style:none;border-top-color:#fff}.side-nav li.heading{color:#ba2619;font-size:.875rem;font-weight:bold;text-transform:uppercase}table{background:#fff;margin-bottom:1.25rem;border:solid 1px #ddd;table-layout:auto}table caption{background:transparent;color:#222;font-size:1rem;font-weight:bold}table thead{background:#f5f5f5}table thead tr th,table thead tr td{padding:.5rem .625rem .625rem;font-size:.875rem;font-weight:700;color:#222}table tfoot{background:#f5f5f5}table tfoot tr th,table tfoot tr td{padding:.5rem .625rem .625rem;font-size:.875rem;font-weight:700;color:#222}table tr th,table tr td{padding:.5625rem .625rem;font-size:.875rem;color:#222;text-align:left}table tr.even,table tr.alt,table tr:nth-of-type(even){background:#F9F9F9}table thead tr th,table tfoot tr th,table tfoot tr td,table tbody tr th,table tbody tr td,table tr td{display:table-cell;line-height:1.125rem}.th{line-height:0;display:inline-block;border:solid 4px #fff;max-width:100%;box-shadow:0 0 0 1px rgba(0,0,0,0.2);transition:all 200ms ease-out}.th:hover,.th:focus{box-shadow:0 0 6px 1px rgba(186,38,25,0.5)}.th.radius{border-radius:3px}meta.foundation-mq-topbar{font-family:"/only screen and (min-width:40.0625em)/";width:40.0625em}.contain-to-grid{width:100%;background:#333}.contain-to-grid .top-bar{margin-bottom:0}.fixed{width:100%;left:0;position:fixed;top:0;z-index:99}.fixed.expanded:not(.top-bar){overflow-y:auto;height:auto;width:100%;max-height:100%}.fixed.expanded:not(.top-bar) .title-area{position:fixed;width:100%;z-index:99}.fixed.expanded:not(.top-bar) .top-bar-section{z-index:98;margin-top:2.8125rem}.top-bar{overflow:hidden;height:2.8125rem;line-height:2.8125rem;position:relative;background:#333;margin-bottom:0}.top-bar ul{margin-bottom:0;list-style:none}.top-bar .row{max-width:none}.top-bar form,.top-bar input{margin-bottom:0}.top-bar input{height:1.75rem;padding-top:.35rem;padding-bottom:.35rem;font-size:.75rem}.top-bar .button,.top-bar button{padding-top:0.4125rem;padding-bottom:0.4125rem;margin-bottom:0;font-size:.75rem}@media only screen and (max-width: 40em){.top-bar .button,.top-bar button{position:relative;top:-1px}}.top-bar .title-area{position:relative;margin:0}.top-bar .name{height:2.8125rem;margin:0;font-size:16px}.top-bar .name h1,.top-bar .name h2,.top-bar .name h3,.top-bar .name h4,.top-bar .name p,.top-bar .name span{line-height:2.8125rem;font-size:1.0625rem;margin:0}.top-bar .name h1 a,.top-bar .name h2 a,.top-bar .name h3 a,.top-bar .name h4 a,.top-bar .name p a,.top-bar .name span a{font-weight:400;color:#fff;width:75%;display:block;padding:0 .9375rem}.top-bar .toggle-topbar{position:absolute;right:0;top:0}.top-bar .toggle-topbar a{color:#fff;text-transform:uppercase;font-size:.8125rem;font-weight:700;position:relative;display:block;padding:0 .9375rem;height:2.8125rem;line-height:2.8125rem}.top-bar .toggle-topbar.menu-icon{top:50%;margin-top:-16px}.top-bar .toggle-topbar.menu-icon a{height:34px;line-height:33px;padding:0 2.5rem 0 .9375rem;color:#fff;position:relative}.top-bar .toggle-topbar.menu-icon a span::after{content:"";position:absolute;display:block;height:0;top:50%;margin-top:-8px;right:.9375rem;box-shadow:0 0 0 1px #fff,0 7px 0 1px #fff,0 14px 0 1px #fff;width:16px}.top-bar .toggle-topbar.menu-icon a span:hover:after{box-shadow:0 0 0 1px "",0 7px 0 1px "",0 14px 0 1px ""}.top-bar.expanded{height:auto;background:transparent}.top-bar.expanded .title-area{background:#333}.top-bar.expanded .toggle-topbar a{color:#888}.top-bar.expanded .toggle-topbar a span::after{box-shadow:0 0 0 1px #888,0 7px 0 1px #888,0 14px 0 1px #888}.top-bar-section{left:0;position:relative;width:auto;transition:left 300ms ease-out}.top-bar-section ul{padding:0;width:100%;height:auto;display:block;font-size:16px;margin:0}.top-bar-section .divider,.top-bar-section [role="separator"]{border-top:solid 1px #1a1919;clear:both;height:1px;width:100%}.top-bar-section ul li{background:#333}.top-bar-section ul li>a{display:block;width:100%;color:#fff;padding:12px 0 12px 0;padding-left:.9375rem;font-family:"Open Sans","Helvetica Neue",Helvetica,Roboto,Arial,sans-serif;font-size:.8125rem;font-weight:400;text-transform:none}.top-bar-section ul li>a.button{font-size:.8125rem;padding-right:.9375rem;padding-left:.9375rem;background-color:#ba2619;border-color:#951e14;color:#fff}.top-bar-section ul li>a.button:hover,.top-bar-section ul li>a.button:focus{background-color:#951e14}.top-bar-section ul li>a.button:hover,.top-bar-section ul li>a.button:focus{color:#fff}.top-bar-section ul li>a.button.secondary{background-color:#e7e7e7;border-color:#b9b9b9;color:#333}.top-bar-section ul li>a.button.secondary:hover,.top-bar-section ul li>a.button.secondary:focus{background-color:#b9b9b9}.top-bar-section ul li>a.button.secondary:hover,.top-bar-section ul li>a.button.secondary:focus{color:#333}.top-bar-section ul li>a.button.success{background-color:#43AC6A;border-color:#368a55;color:#fff}.top-bar-section ul li>a.button.success:hover,.top-bar-section ul li>a.button.success:focus{background-color:#368a55}.top-bar-section ul li>a.button.success:hover,.top-bar-section ul li>a.button.success:focus{color:#fff}.top-bar-section ul li>a.button.alert{background-color:#f04124;border-color:#cf2a0e;color:#fff}.top-bar-section ul li>a.button.alert:hover,.top-bar-section ul li>a.button.alert:focus{background-color:#cf2a0e}.top-bar-section ul li>a.button.alert:hover,.top-bar-section ul li>a.button.alert:focus{color:#fff}.top-bar-section ul li>a.button.warning{background-color:#f08a24;border-color:#cf6e0e;color:#fff}.top-bar-section ul li>a.button.warning:hover,.top-bar-section ul li>a.button.warning:focus{background-color:#cf6e0e}.top-bar-section ul li>a.button.warning:hover,.top-bar-section ul li>a.button.warning:focus{color:#fff}.top-bar-section ul li>button{font-size:.8125rem;padding-right:.9375rem;padding-left:.9375rem;background-color:#ba2619;border-color:#951e14;color:#fff}.top-bar-section ul li>button:hover,.top-bar-section ul li>button:focus{background-color:#951e14}.top-bar-section ul li>button:hover,.top-bar-section ul li>button:focus{color:#fff}.top-bar-section ul li>button.secondary{background-color:#e7e7e7;border-color:#b9b9b9;color:#333}.top-bar-section ul li>button.secondary:hover,.top-bar-section ul li>button.secondary:focus{background-color:#b9b9b9}.top-bar-section ul li>button.secondary:hover,.top-bar-section ul li>button.secondary:focus{color:#333}.top-bar-section ul li>button.success{background-color:#43AC6A;border-color:#368a55;color:#fff}.top-bar-section ul li>button.success:hover,.top-bar-section ul li>button.success:focus{background-color:#368a55}.top-bar-section ul li>button.success:hover,.top-bar-section ul li>button.success:focus{color:#fff}.top-bar-section ul li>button.alert{background-color:#f04124;border-color:#cf2a0e;color:#fff}.top-bar-section ul li>button.alert:hover,.top-bar-section ul li>button.alert:focus{background-color:#cf2a0e}.top-bar-section ul li>button.alert:hover,.top-bar-section ul li>button.alert:focus{color:#fff}.top-bar-section ul li>button.warning{background-color:#f08a24;border-color:#cf6e0e;color:#fff}.top-bar-section ul li>button.warning:hover,.top-bar-section ul li>button.warning:focus{background-color:#cf6e0e}.top-bar-section ul li>button.warning:hover,.top-bar-section ul li>button.warning:focus{color:#fff}.top-bar-section ul li:hover:not(.has-form)>a{background-color:#555;background:#333;color:#fff}.top-bar-section ul li.active>a{background:#ba2619;color:#fff}.top-bar-section ul li.active>a:hover{background:#a02116;color:#fff}.top-bar-section .has-form{padding:.9375rem}.top-bar-section .has-dropdown{position:relative}.top-bar-section .has-dropdown>a:after{content:"";display:block;width:0;height:0;border:inset 5px;border-color:transparent transparent transparent rgba(255,255,255,0.4);border-left-style:solid;margin-right:.9375rem;margin-top:-4.5px;position:absolute;top:50%;right:0}.top-bar-section .has-dropdown.moved{position:static}.top-bar-section .has-dropdown.moved>.dropdown{display:block;position:static !important;height:auto;width:auto;overflow:visible;clip:auto;position:absolute !important;width:100%}.top-bar-section .has-dropdown.moved>a:after{display:none}.top-bar-section .dropdown{padding:0;position:absolute;left:100%;top:0;z-index:99;display:block;position:absolute !important;height:1px;width:1px;overflow:hidden;clip:rect(1px, 1px, 1px, 1px)}.top-bar-section .dropdown li{width:100%;height:auto}.top-bar-section .dropdown li a{font-weight:400;padding:8px .9375rem}.top-bar-section .dropdown li a.parent-link{font-weight:400}.top-bar-section .dropdown li.title h5,.top-bar-section .dropdown li.parent-link{margin-bottom:0;margin-top:0;font-size:1.125rem}.top-bar-section .dropdown li.title h5 a,.top-bar-section .dropdown li.parent-link a{color:#fff;display:block}.top-bar-section .dropdown li.title h5 a:hover,.top-bar-section .dropdown li.parent-link a:hover{background:none}.top-bar-section .dropdown li.has-form{padding:8px .9375rem}.top-bar-section .dropdown li .button,.top-bar-section .dropdown li button{top:auto}.top-bar-section .dropdown label{padding:8px .9375rem 2px;margin-bottom:0;text-transform:uppercase;color:#777;font-weight:700;font-size:.625rem}.js-generated{display:block}@media only screen and (min-width: 40.0625em){.top-bar{background:#333;overflow:visible}.top-bar:before,.top-bar:after{content:" ";display:table}.top-bar:after{clear:both}.top-bar .toggle-topbar{display:none}.top-bar .title-area{float:left}.top-bar .name h1 a,.top-bar .name h2 a,.top-bar .name h3 a,.top-bar .name h4 a,.top-bar .name h5 a,.top-bar .name h6 a{width:auto}.top-bar input,.top-bar .button,.top-bar button{font-size:.875rem;position:relative;height:1.75rem;top:.53125rem}.top-bar.expanded{background:#333}.contain-to-grid .top-bar{max-width:62.5rem;margin:0 auto;margin-bottom:0}.top-bar-section{transition:none 0 0;left:0 !important}.top-bar-section ul{width:auto;height:auto !important;display:inline}.top-bar-section ul li{float:left}.top-bar-section ul li .js-generated{display:none}.top-bar-section li.hover>a:not(.button){background-color:#555;background:#333;color:#fff}.top-bar-section li:not(.has-form) a:not(.button){padding:0 .9375rem;line-height:2.8125rem;background:#333}.top-bar-section li:not(.has-form) a:not(.button):hover{background-color:#555;background:#333}.top-bar-section li.active:not(.has-form) a:not(.button){padding:0 .9375rem;line-height:2.8125rem;color:#fff;background:#ba2619}.top-bar-section li.active:not(.has-form) a:not(.button):hover{background:#a02116;color:#fff}.top-bar-section .has-dropdown>a{padding-right:2.1875rem !important}.top-bar-section .has-dropdown>a:after{content:"";display:block;width:0;height:0;border:inset 5px;border-color:rgba(255,255,255,0.4) transparent transparent transparent;border-top-style:solid;margin-top:-2.5px;top:1.40625rem}.top-bar-section .has-dropdown.moved{position:relative}.top-bar-section .has-dropdown.moved>.dropdown{display:block;position:absolute !important;height:1px;width:1px;overflow:hidden;clip:rect(1px, 1px, 1px, 1px)}.top-bar-section .has-dropdown.hover>.dropdown,.top-bar-section .has-dropdown.not-click:hover>.dropdown{display:block;position:static !important;height:auto;width:auto;overflow:visible;clip:auto;position:absolute !important}.top-bar-section .has-dropdown>a:focus+.dropdown{display:block;position:static !important;height:auto;width:auto;overflow:visible;clip:auto;position:absolute !important}.top-bar-section .has-dropdown .dropdown li.has-dropdown>a:after{border:none;content:"\00bb";top:1rem;margin-top:-1px;right:5px;line-height:1.2}.top-bar-section .dropdown{left:0;top:auto;background:transparent;min-width:100%}.top-bar-section .dropdown li a{color:#fff;line-height:2.8125rem;white-space:nowrap;padding:12px .9375rem;background:#333}.top-bar-section .dropdown li:not(.has-form):not(.active)>a:not(.button){color:#fff;background:#333}.top-bar-section .dropdown li:not(.has-form):not(.active):hover>a:not(.button){color:#fff;background-color:#555;background:#333}.top-bar-section .dropdown li label{white-space:nowrap;background:#333}.top-bar-section .dropdown li .dropdown{left:100%;top:0}.top-bar-section>ul>.divider,.top-bar-section>ul>[role="separator"]{border-bottom:none;border-top:none;border-right:solid 1px #4e4e4e;clear:none;height:2.8125rem;width:0}.top-bar-section .has-form{background:#333;padding:0 .9375rem;height:2.8125rem}.top-bar-section .right li .dropdown{left:auto;right:0}.top-bar-section .right li .dropdown li .dropdown{right:100%}.top-bar-section .left li .dropdown{right:auto;left:0}.top-bar-section .left li .dropdown li .dropdown{left:100%}.no-js .top-bar-section ul li:hover>a{background-color:#555;background:#333;color:#fff}.no-js .top-bar-section ul li:active>a{background:#ba2619;color:#fff}.no-js .top-bar-section .has-dropdown:hover>.dropdown{display:block;position:static !important;height:auto;width:auto;overflow:visible;clip:auto;position:absolute !important}.no-js .top-bar-section .has-dropdown>a:focus+.dropdown{display:block;position:static !important;height:auto;width:auto;overflow:visible;clip:auto;position:absolute !important}}.text-left{text-align:left !important}.text-right{text-align:right !important}.text-center{text-align:center !important}.text-justify{text-align:justify !important}@media only screen and (max-width: 40em){.small-only-text-left{text-align:left !important}.small-only-text-right{text-align:right !important}.small-only-text-center{text-align:center !important}.small-only-text-justify{text-align:justify !important}}@media only screen{.small-text-left{text-align:left !important}.small-text-right{text-align:right !important}.small-text-center{text-align:center !important}.small-text-justify{text-align:justify !important}}@media only screen and (min-width: 40.0625em) and (max-width: 64em){.medium-only-text-left{text-align:left !important}.medium-only-text-right{text-align:right !important}.medium-only-text-center{text-align:center !important}.medium-only-text-justify{text-align:justify !important}}@media only screen and (min-width: 40.0625em){.medium-text-left{text-align:left !important}.medium-text-right{text-align:right !important}.medium-text-center{text-align:center !important}.medium-text-justify{text-align:justify !important}}@media only screen and (min-width: 64.0625em) and (max-width: 90em){.large-only-text-left{text-align:left !important}.large-only-text-right{text-align:right !important}.large-only-text-center{text-align:center !important}.large-only-text-justify{text-align:justify !important}}@media only screen and (min-width: 64.0625em){.large-text-left{text-align:left !important}.large-text-right{text-align:right !important}.large-text-center{text-align:center !important}.large-text-justify{text-align:justify !important}}@media only screen and (min-width: 90.0625em) and (max-width: 120em){.xlarge-only-text-left{text-align:left !important}.xlarge-only-text-right{text-align:right !important}.xlarge-only-text-center{text-align:center !important}.xlarge-only-text-justify{text-align:justify !important}}@media only screen and (min-width: 90.0625em){.xlarge-text-left{text-align:left !important}.xlarge-text-right{text-align:right !important}.xlarge-text-center{text-align:center !important}.xlarge-text-justify{text-align:justify !important}}@media only screen and (min-width: 120.0625em) and (max-width: 99999999em){.xxlarge-only-text-left{text-align:left !important}.xxlarge-only-text-right{text-align:right !important}.xxlarge-only-text-center{text-align:center !important}.xxlarge-only-text-justify{text-align:justify !important}}@media only screen and (min-width: 120.0625em){.xxlarge-text-left{text-align:left !important}.xxlarge-text-right{text-align:right !important}.xxlarge-text-center{text-align:center !important}.xxlarge-text-justify{text-align:justify !important}}div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0}a{color:#ba2619;text-decoration:none;line-height:inherit}a:hover,a:focus{color:#a02116}a img{border:none}p{font-family:inherit;font-weight:400;font-size:1rem;line-height:1.6;margin-bottom:1.25rem;text-rendering:optimizeLegibility}p.lead{font-size:1.21875rem;line-height:1.6}p aside{font-size:.875rem;line-height:1.35;font-style:italic}h1,h2,h3,h4,h5,h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Roboto,Arial,sans-serif;font-weight:700;font-style:normal;color:#222;text-rendering:optimizeLegibility;margin-top:.2rem;margin-bottom:.5rem;line-height:1.4}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-size:80%;color:#6f6f6f;line-height:0}h1{font-size:1.5625rem}h2{font-size:1.25rem}h3{font-size:1.0625rem}h4{font-size:.9375rem}h5{font-size:1rem}h6{font-size:1rem}.subheader{line-height:1.4;color:#6f6f6f;font-weight:400;margin-top:.2rem;margin-bottom:.5rem}hr{border:solid #ddd;border-width:1px 0 0;clear:both;margin:1.25rem 0 1.1875rem;height:0}em,i{font-style:italic;line-height:inherit}strong,b{font-weight:700;line-height:inherit}small{font-size:80%;line-height:inherit}code{font-family:Consolas,"Liberation Mono",Courier,monospace;font-weight:400;color:#333;background-color:rgba(0,0,0,0.04);border-width:1px;border-style:none;border-color:rgba(0,0,0,0.04);padding:.125rem .3125rem .0625rem}ul,ol,dl{font-size:1rem;line-height:1.6;margin-bottom:1.25rem;list-style-position:outside;font-family:inherit}ul{margin-left:1.1rem}ul.no-bullet{margin-left:0}ul.no-bullet li ul,ul.no-bullet li ol{margin-left:1.25rem;margin-bottom:0;list-style:none}ul li ul,ul li ol{margin-left:1.25rem;margin-bottom:0}ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}ul.square{list-style-type:square;margin-left:1.1rem}ul.circle{list-style-type:circle;margin-left:1.1rem}ul.disc{list-style-type:disc;margin-left:1.1rem}ul.no-bullet{list-style:none}ol{margin-left:1.4rem}ol li ul,ol li ol{margin-left:1.25rem;margin-bottom:0}dl dt{margin-bottom:.3rem;font-weight:700}dl dd{margin-bottom:.75rem}abbr,acronym{text-transform:uppercase;font-size:90%;color:#222;cursor:help}abbr{text-transform:none}abbr[title]{border-bottom:1px dotted #ddd}blockquote{margin:0 0 1.25rem;padding:.5625rem 1.25rem 0 1.1875rem;border-left:1px solid #ddd}blockquote cite{display:block;font-size:.8125rem;color:#555}blockquote cite:before{content:"\2014 \0020"}blockquote cite a,blockquote cite a:visited{color:#555}blockquote,blockquote p{line-height:1.6;color:#6f6f6f}.vcard{display:inline-block;margin:0 0 1.25rem 0;border:1px solid #ddd;padding:.625rem .75rem}.vcard li{margin:0;display:block}.vcard .fn{font-weight:700;font-size:.9375rem}.vevent .summary{font-weight:700}.vevent abbr{cursor:default;text-decoration:none;font-weight:700;border:none;padding:0 .0625rem}@media only screen and (min-width: 40.0625em){h1,h2,h3,h4,h5,h6{line-height:1.4}h1{font-size:1.875rem}h2{font-size:1.5625rem}h3{font-size:1.375rem}h4{font-size:1.25rem}h5{font-size:1rem}h6{font-size:1rem}}@media only screen{.show-for-small-only,.show-for-small-up,.show-for-small,.show-for-small-down,.hide-for-medium-only,.hide-for-medium-up,.hide-for-medium,.show-for-medium-down,.hide-for-large-only,.hide-for-large-up,.hide-for-large,.show-for-large-down,.hide-for-xlarge-only,.hide-for-xlarge-up,.hide-for-xlarge,.show-for-xlarge-down,.hide-for-xxlarge-only,.hide-for-xxlarge-up,.hide-for-xxlarge,.show-for-xxlarge-down{display:inherit !important}.hide-for-small-only,.hide-for-small-up,.hide-for-small,.hide-for-small-down,.show-for-medium-only,.show-for-medium-up,.show-for-medium,.hide-for-medium-down,.show-for-large-only,.show-for-large-up,.show-for-large,.hide-for-large-down,.show-for-xlarge-only,.show-for-xlarge-up,.show-for-xlarge,.hide-for-xlarge-down,.show-for-xxlarge-only,.show-for-xxlarge-up,.show-for-xxlarge,.hide-for-xxlarge-down{display:none !important}.visible-for-small-only,.visible-for-small-up,.visible-for-small,.visible-for-small-down,.hidden-for-medium-only,.hidden-for-medium-up,.hidden-for-medium,.visible-for-medium-down,.hidden-for-large-only,.hidden-for-large-up,.hidden-for-large,.visible-for-large-down,.hidden-for-xlarge-only,.hidden-for-xlarge-up,.hidden-for-xlarge,.visible-for-xlarge-down,.hidden-for-xxlarge-only,.hidden-for-xxlarge-up,.hidden-for-xxlarge,.visible-for-xxlarge-down{position:static !important;height:auto;width:auto;overflow:visible;clip:auto}.hidden-for-small-only,.hidden-for-small-up,.hidden-for-small,.hidden-for-small-down,.visible-for-medium-only,.visible-for-medium-up,.visible-for-medium,.hidden-for-medium-down,.visible-for-large-only,.visible-for-large-up,.visible-for-large,.hidden-for-large-down,.visible-for-xlarge-only,.visible-for-xlarge-up,.visible-for-xlarge,.hidden-for-xlarge-down,.visible-for-xxlarge-only,.visible-for-xxlarge-up,.visible-for-xxlarge,.hidden-for-xxlarge-down{position:absolute !important;height:1px;width:1px;overflow:hidden;clip:rect(1px, 1px, 1px, 1px)}table.show-for-small-only,table.show-for-small-up,table.show-for-small,table.show-for-small-down,table.hide-for-medium-only,table.hide-for-medium-up,table.hide-for-medium,table.show-for-medium-down,table.hide-for-large-only,table.hide-for-large-up,table.hide-for-large,table.show-for-large-down,table.hide-for-xlarge-only,table.hide-for-xlarge-up,table.hide-for-xlarge,table.show-for-xlarge-down,table.hide-for-xxlarge-only,table.hide-for-xxlarge-up,table.hide-for-xxlarge,table.show-for-xxlarge-down{display:table !important}thead.show-for-small-only,thead.show-for-small-up,thead.show-for-small,thead.show-for-small-down,thead.hide-for-medium-only,thead.hide-for-medium-up,thead.hide-for-medium,thead.show-for-medium-down,thead.hide-for-large-only,thead.hide-for-large-up,thead.hide-for-large,thead.show-for-large-down,thead.hide-for-xlarge-only,thead.hide-for-xlarge-up,thead.hide-for-xlarge,thead.show-for-xlarge-down,thead.hide-for-xxlarge-only,thead.hide-for-xxlarge-up,thead.hide-for-xxlarge,thead.show-for-xxlarge-down{display:table-header-group !important}tbody.show-for-small-only,tbody.show-for-small-up,tbody.show-for-small,tbody.show-for-small-down,tbody.hide-for-medium-only,tbody.hide-for-medium-up,tbody.hide-for-medium,tbody.show-for-medium-down,tbody.hide-for-large-only,tbody.hide-for-large-up,tbody.hide-for-large,tbody.show-for-large-down,tbody.hide-for-xlarge-only,tbody.hide-for-xlarge-up,tbody.hide-for-xlarge,tbody.show-for-xlarge-down,tbody.hide-for-xxlarge-only,tbody.hide-for-xxlarge-up,tbody.hide-for-xxlarge,tbody.show-for-xxlarge-down{display:table-row-group !important}tr.show-for-small-only,tr.show-for-small-up,tr.show-for-small,tr.show-for-small-down,tr.hide-for-medium-only,tr.hide-for-medium-up,tr.hide-for-medium,tr.show-for-medium-down,tr.hide-for-large-only,tr.hide-for-large-up,tr.hide-for-large,tr.show-for-large-down,tr.hide-for-xlarge-only,tr.hide-for-xlarge-up,tr.hide-for-xlarge,tr.show-for-xlarge-down,tr.hide-for-xxlarge-only,tr.hide-for-xxlarge-up,tr.hide-for-xxlarge,tr.show-for-xxlarge-down{display:table-row}th.show-for-small-only,td.show-for-small-only,th.show-for-small-up,td.show-for-small-up,th.show-for-small,td.show-for-small,th.show-for-small-down,td.show-for-small-down,th.hide-for-medium-only,td.hide-for-medium-only,th.hide-for-medium-up,td.hide-for-medium-up,th.hide-for-medium,td.hide-for-medium,th.show-for-medium-down,td.show-for-medium-down,th.hide-for-large-only,td.hide-for-large-only,th.hide-for-large-up,td.hide-for-large-up,th.hide-for-large,td.hide-for-large,th.show-for-large-down,td.show-for-large-down,th.hide-for-xlarge-only,td.hide-for-xlarge-only,th.hide-for-xlarge-up,td.hide-for-xlarge-up,th.hide-for-xlarge,td.hide-for-xlarge,th.show-for-xlarge-down,td.show-for-xlarge-down,th.hide-for-xxlarge-only,td.hide-for-xxlarge-only,th.hide-for-xxlarge-up,td.hide-for-xxlarge-up,th.hide-for-xxlarge,td.hide-for-xxlarge,th.show-for-xxlarge-down,td.show-for-xxlarge-down{display:table-cell !important}}@media only screen and (min-width: 40.0625em){.hide-for-small-only,.show-for-small-up,.hide-for-small,.hide-for-small-down,.show-for-medium-only,.show-for-medium-up,.show-for-medium,.show-for-medium-down,.hide-for-large-only,.hide-for-large-up,.hide-for-large,.show-for-large-down,.hide-for-xlarge-only,.hide-for-xlarge-up,.hide-for-xlarge,.show-for-xlarge-down,.hide-for-xxlarge-only,.hide-for-xxlarge-up,.hide-for-xxlarge,.show-for-xxlarge-down{display:inherit !important}.show-for-small-only,.hide-for-small-up,.show-for-small,.show-for-small-down,.hide-for-medium-only,.hide-for-medium-up,.hide-for-medium,.hide-for-medium-down,.show-for-large-only,.show-for-large-up,.show-for-large,.hide-for-large-down,.show-for-xlarge-only,.show-for-xlarge-up,.show-for-xlarge,.hide-for-xlarge-down,.show-for-xxlarge-only,.show-for-xxlarge-up,.show-for-xxlarge,.hide-for-xxlarge-down{display:none !important}.hidden-for-small-only,.visible-for-small-up,.hidden-for-small,.hidden-for-small-down,.visible-for-medium-only,.visible-for-medium-up,.visible-for-medium,.visible-for-medium-down,.hidden-for-large-only,.hidden-for-large-up,.hidden-for-large,.visible-for-large-down,.hidden-for-xlarge-only,.hidden-for-xlarge-up,.hidden-for-xlarge,.visible-for-xlarge-down,.hidden-for-xxlarge-only,.hidden-for-xxlarge-up,.hidden-for-xxlarge,.visible-for-xxlarge-down{position:static !important;height:auto;width:auto;overflow:visible;clip:auto}.visible-for-small-only,.hidden-for-small-up,.visible-for-small,.visible-for-small-down,.hidden-for-medium-only,.hidden-for-medium-up,.hidden-for-medium,.hidden-for-medium-down,.visible-for-large-only,.visible-for-large-up,.visible-for-large,.hidden-for-large-down,.visible-for-xlarge-only,.visible-for-xlarge-up,.visible-for-xlarge,.hidden-for-xlarge-down,.visible-for-xxlarge-only,.visible-for-xxlarge-up,.visible-for-xxlarge,.hidden-for-xxlarge-down{position:absolute !important;height:1px;width:1px;overflow:hidden;clip:rect(1px, 1px, 1px, 1px)}table.hide-for-small-only,table.show-for-small-up,table.hide-for-small,table.hide-for-small-down,table.show-for-medium-only,table.show-for-medium-up,table.show-for-medium,table.show-for-medium-down,table.hide-for-large-only,table.hide-for-large-up,table.hide-for-large,table.show-for-large-down,table.hide-for-xlarge-only,table.hide-for-xlarge-up,table.hide-for-xlarge,table.show-for-xlarge-down,table.hide-for-xxlarge-only,table.hide-for-xxlarge-up,table.hide-for-xxlarge,table.show-for-xxlarge-down{display:table !important}thead.hide-for-small-only,thead.show-for-small-up,thead.hide-for-small,thead.hide-for-small-down,thead.show-for-medium-only,thead.show-for-medium-up,thead.show-for-medium,thead.show-for-medium-down,thead.hide-for-large-only,thead.hide-for-large-up,thead.hide-for-large,thead.show-for-large-down,thead.hide-for-xlarge-only,thead.hide-for-xlarge-up,thead.hide-for-xlarge,thead.show-for-xlarge-down,thead.hide-for-xxlarge-only,thead.hide-for-xxlarge-up,thead.hide-for-xxlarge,thead.show-for-xxlarge-down{display:table-header-group !important}tbody.hide-for-small-only,tbody.show-for-small-up,tbody.hide-for-small,tbody.hide-for-small-down,tbody.show-for-medium-only,tbody.show-for-medium-up,tbody.show-for-medium,tbody.show-for-medium-down,tbody.hide-for-large-only,tbody.hide-for-large-up,tbody.hide-for-large,tbody.show-for-large-down,tbody.hide-for-xlarge-only,tbody.hide-for-xlarge-up,tbody.hide-for-xlarge,tbody.show-for-xlarge-down,tbody.hide-for-xxlarge-only,tbody.hide-for-xxlarge-up,tbody.hide-for-xxlarge,tbody.show-for-xxlarge-down{display:table-row-group !important}tr.hide-for-small-only,tr.show-for-small-up,tr.hide-for-small,tr.hide-for-small-down,tr.show-for-medium-only,tr.show-for-medium-up,tr.show-for-medium,tr.show-for-medium-down,tr.hide-for-large-only,tr.hide-for-large-up,tr.hide-for-large,tr.show-for-large-down,tr.hide-for-xlarge-only,tr.hide-for-xlarge-up,tr.hide-for-xlarge,tr.show-for-xlarge-down,tr.hide-for-xxlarge-only,tr.hide-for-xxlarge-up,tr.hide-for-xxlarge,tr.show-for-xxlarge-down{display:table-row}th.hide-for-small-only,td.hide-for-small-only,th.show-for-small-up,td.show-for-small-up,th.hide-for-small,td.hide-for-small,th.hide-for-small-down,td.hide-for-small-down,th.show-for-medium-only,td.show-for-medium-only,th.show-for-medium-up,td.show-for-medium-up,th.show-for-medium,td.show-for-medium,th.show-for-medium-down,td.show-for-medium-down,th.hide-for-large-only,td.hide-for-large-only,th.hide-for-large-up,td.hide-for-large-up,th.hide-for-large,td.hide-for-large,th.show-for-large-down,td.show-for-large-down,th.hide-for-xlarge-only,td.hide-for-xlarge-only,th.hide-for-xlarge-up,td.hide-for-xlarge-up,th.hide-for-xlarge,td.hide-for-xlarge,th.show-for-xlarge-down,td.show-for-xlarge-down,th.hide-for-xxlarge-only,td.hide-for-xxlarge-only,th.hide-for-xxlarge-up,td.hide-for-xxlarge-up,th.hide-for-xxlarge,td.hide-for-xxlarge,th.show-for-xxlarge-down,td.show-for-xxlarge-down{display:table-cell !important}}@media only screen and (min-width: 64.0625em){.hide-for-small-only,.show-for-small-up,.hide-for-small,.hide-for-small-down,.hide-for-medium-only,.show-for-medium-up,.hide-for-medium,.hide-for-medium-down,.show-for-large-only,.show-for-large-up,.show-for-large,.show-for-large-down,.hide-for-xlarge-only,.hide-for-xlarge-up,.hide-for-xlarge,.show-for-xlarge-down,.hide-for-xxlarge-only,.hide-for-xxlarge-up,.hide-for-xxlarge,.show-for-xxlarge-down{display:inherit !important}.show-for-small-only,.hide-for-small-up,.show-for-small,.show-for-small-down,.show-for-medium-only,.hide-for-medium-up,.show-for-medium,.show-for-medium-down,.hide-for-large-only,.hide-for-large-up,.hide-for-large,.hide-for-large-down,.show-for-xlarge-only,.show-for-xlarge-up,.show-for-xlarge,.hide-for-xlarge-down,.show-for-xxlarge-only,.show-for-xxlarge-up,.show-for-xxlarge,.hide-for-xxlarge-down{display:none !important}.hidden-for-small-only,.visible-for-small-up,.hidden-for-small,.hidden-for-small-down,.hidden-for-medium-only,.visible-for-medium-up,.hidden-for-medium,.hidden-for-medium-down,.visible-for-large-only,.visible-for-large-up,.visible-for-large,.visible-for-large-down,.hidden-for-xlarge-only,.hidden-for-xlarge-up,.hidden-for-xlarge,.visible-for-xlarge-down,.hidden-for-xxlarge-only,.hidden-for-xxlarge-up,.hidden-for-xxlarge,.visible-for-xxlarge-down{position:static !important;height:auto;width:auto;overflow:visible;clip:auto}.visible-for-small-only,.hidden-for-small-up,.visible-for-small,.visible-for-small-down,.visible-for-medium-only,.hidden-for-medium-up,.visible-for-medium,.visible-for-medium-down,.hidden-for-large-only,.hidden-for-large-up,.hidden-for-large,.hidden-for-large-down,.visible-for-xlarge-only,.visible-for-xlarge-up,.visible-for-xlarge,.hidden-for-xlarge-down,.visible-for-xxlarge-only,.visible-for-xxlarge-up,.visible-for-xxlarge,.hidden-for-xxlarge-down{position:absolute !important;height:1px;width:1px;overflow:hidden;clip:rect(1px, 1px, 1px, 1px)}table.hide-for-small-only,table.show-for-small-up,table.hide-for-small,table.hide-for-small-down,table.hide-for-medium-only,table.show-for-medium-up,table.hide-for-medium,table.hide-for-medium-down,table.show-for-large-only,table.show-for-large-up,table.show-for-large,table.show-for-large-down,table.hide-for-xlarge-only,table.hide-for-xlarge-up,table.hide-for-xlarge,table.show-for-xlarge-down,table.hide-for-xxlarge-only,table.hide-for-xxlarge-up,table.hide-for-xxlarge,table.show-for-xxlarge-down{display:table !important}thead.hide-for-small-only,thead.show-for-small-up,thead.hide-for-small,thead.hide-for-small-down,thead.hide-for-medium-only,thead.show-for-medium-up,thead.hide-for-medium,thead.hide-for-medium-down,thead.show-for-large-only,thead.show-for-large-up,thead.show-for-large,thead.show-for-large-down,thead.hide-for-xlarge-only,thead.hide-for-xlarge-up,thead.hide-for-xlarge,thead.show-for-xlarge-down,thead.hide-for-xxlarge-only,thead.hide-for-xxlarge-up,thead.hide-for-xxlarge,thead.show-for-xxlarge-down{display:table-header-group !important}tbody.hide-for-small-only,tbody.show-for-small-up,tbody.hide-for-small,tbody.hide-for-small-down,tbody.hide-for-medium-only,tbody.show-for-medium-up,tbody.hide-for-medium,tbody.hide-for-medium-down,tbody.show-for-large-only,tbody.show-for-large-up,tbody.show-for-large,tbody.show-for-large-down,tbody.hide-for-xlarge-only,tbody.hide-for-xlarge-up,tbody.hide-for-xlarge,tbody.show-for-xlarge-down,tbody.hide-for-xxlarge-only,tbody.hide-for-xxlarge-up,tbody.hide-for-xxlarge,tbody.show-for-xxlarge-down{display:table-row-group !important}tr.hide-for-small-only,tr.show-for-small-up,tr.hide-for-small,tr.hide-for-small-down,tr.hide-for-medium-only,tr.show-for-medium-up,tr.hide-for-medium,tr.hide-for-medium-down,tr.show-for-large-only,tr.show-for-large-up,tr.show-for-large,tr.show-for-large-down,tr.hide-for-xlarge-only,tr.hide-for-xlarge-up,tr.hide-for-xlarge,tr.show-for-xlarge-down,tr.hide-for-xxlarge-only,tr.hide-for-xxlarge-up,tr.hide-for-xxlarge,tr.show-for-xxlarge-down{display:table-row}th.hide-for-small-only,td.hide-for-small-only,th.show-for-small-up,td.show-for-small-up,th.hide-for-small,td.hide-for-small,th.hide-for-small-down,td.hide-for-small-down,th.hide-for-medium-only,td.hide-for-medium-only,th.show-for-medium-up,td.show-for-medium-up,th.hide-for-medium,td.hide-for-medium,th.hide-for-medium-down,td.hide-for-medium-down,th.show-for-large-only,td.show-for-large-only,th.show-for-large-up,td.show-for-large-up,th.show-for-large,td.show-for-large,th.show-for-large-down,td.show-for-large-down,th.hide-for-xlarge-only,td.hide-for-xlarge-only,th.hide-for-xlarge-up,td.hide-for-xlarge-up,th.hide-for-xlarge,td.hide-for-xlarge,th.show-for-xlarge-down,td.show-for-xlarge-down,th.hide-for-xxlarge-only,td.hide-for-xxlarge-only,th.hide-for-xxlarge-up,td.hide-for-xxlarge-up,th.hide-for-xxlarge,td.hide-for-xxlarge,th.show-for-xxlarge-down,td.show-for-xxlarge-down{display:table-cell !important}}@media only screen and (min-width: 90.0625em){.hide-for-small-only,.show-for-small-up,.hide-for-small,.hide-for-small-down,.hide-for-medium-only,.show-for-medium-up,.hide-for-medium,.hide-for-medium-down,.hide-for-large-only,.show-for-large-up,.hide-for-large,.hide-for-large-down,.show-for-xlarge-only,.show-for-xlarge-up,.show-for-xlarge,.show-for-xlarge-down,.hide-for-xxlarge-only,.hide-for-xxlarge-up,.hide-for-xxlarge,.show-for-xxlarge-down{display:inherit !important}.show-for-small-only,.hide-for-small-up,.show-for-small,.show-for-small-down,.show-for-medium-only,.hide-for-medium-up,.show-for-medium,.show-for-medium-down,.show-for-large-only,.hide-for-large-up,.show-for-large,.show-for-large-down,.hide-for-xlarge-only,.hide-for-xlarge-up,.hide-for-xlarge,.hide-for-xlarge-down,.show-for-xxlarge-only,.show-for-xxlarge-up,.show-for-xxlarge,.hide-for-xxlarge-down{display:none !important}.hidden-for-small-only,.visible-for-small-up,.hidden-for-small,.hidden-for-small-down,.hidden-for-medium-only,.visible-for-medium-up,.hidden-for-medium,.hidden-for-medium-down,.hidden-for-large-only,.visible-for-large-up,.hidden-for-large,.hidden-for-large-down,.visible-for-xlarge-only,.visible-for-xlarge-up,.visible-for-xlarge,.visible-for-xlarge-down,.hidden-for-xxlarge-only,.hidden-for-xxlarge-up,.hidden-for-xxlarge,.visible-for-xxlarge-down{position:static !important;height:auto;width:auto;overflow:visible;clip:auto}.visible-for-small-only,.hidden-for-small-up,.visible-for-small,.visible-for-small-down,.visible-for-medium-only,.hidden-for-medium-up,.visible-for-medium,.visible-for-medium-down,.visible-for-large-only,.hidden-for-large-up,.visible-for-large,.visible-for-large-down,.hidden-for-xlarge-only,.hidden-for-xlarge-up,.hidden-for-xlarge,.hidden-for-xlarge-down,.visible-for-xxlarge-only,.visible-for-xxlarge-up,.visible-for-xxlarge,.hidden-for-xxlarge-down{position:absolute !important;height:1px;width:1px;overflow:hidden;clip:rect(1px, 1px, 1px, 1px)}table.hide-for-small-only,table.show-for-small-up,table.hide-for-small,table.hide-for-small-down,table.hide-for-medium-only,table.show-for-medium-up,table.hide-for-medium,table.hide-for-medium-down,table.hide-for-large-only,table.show-for-large-up,table.hide-for-large,table.hide-for-large-down,table.show-for-xlarge-only,table.show-for-xlarge-up,table.show-for-xlarge,table.show-for-xlarge-down,table.hide-for-xxlarge-only,table.hide-for-xxlarge-up,table.hide-for-xxlarge,table.show-for-xxlarge-down{display:table !important}thead.hide-for-small-only,thead.show-for-small-up,thead.hide-for-small,thead.hide-for-small-down,thead.hide-for-medium-only,thead.show-for-medium-up,thead.hide-for-medium,thead.hide-for-medium-down,thead.hide-for-large-only,thead.show-for-large-up,thead.hide-for-large,thead.hide-for-large-down,thead.show-for-xlarge-only,thead.show-for-xlarge-up,thead.show-for-xlarge,thead.show-for-xlarge-down,thead.hide-for-xxlarge-only,thead.hide-for-xxlarge-up,thead.hide-for-xxlarge,thead.show-for-xxlarge-down{display:table-header-group !important}tbody.hide-for-small-only,tbody.show-for-small-up,tbody.hide-for-small,tbody.hide-for-small-down,tbody.hide-for-medium-only,tbody.show-for-medium-up,tbody.hide-for-medium,tbody.hide-for-medium-down,tbody.hide-for-large-only,tbody.show-for-large-up,tbody.hide-for-large,tbody.hide-for-large-down,tbody.show-for-xlarge-only,tbody.show-for-xlarge-up,tbody.show-for-xlarge,tbody.show-for-xlarge-down,tbody.hide-for-xxlarge-only,tbody.hide-for-xxlarge-up,tbody.hide-for-xxlarge,tbody.show-for-xxlarge-down{display:table-row-group !important}tr.hide-for-small-only,tr.show-for-small-up,tr.hide-for-small,tr.hide-for-small-down,tr.hide-for-medium-only,tr.show-for-medium-up,tr.hide-for-medium,tr.hide-for-medium-down,tr.hide-for-large-only,tr.show-for-large-up,tr.hide-for-large,tr.hide-for-large-down,tr.show-for-xlarge-only,tr.show-for-xlarge-up,tr.show-for-xlarge,tr.show-for-xlarge-down,tr.hide-for-xxlarge-only,tr.hide-for-xxlarge-up,tr.hide-for-xxlarge,tr.show-for-xxlarge-down{display:table-row}th.hide-for-small-only,td.hide-for-small-only,th.show-for-small-up,td.show-for-small-up,th.hide-for-small,td.hide-for-small,th.hide-for-small-down,td.hide-for-small-down,th.hide-for-medium-only,td.hide-for-medium-only,th.show-for-medium-up,td.show-for-medium-up,th.hide-for-medium,td.hide-for-medium,th.hide-for-medium-down,td.hide-for-medium-down,th.hide-for-large-only,td.hide-for-large-only,th.show-for-large-up,td.show-for-large-up,th.hide-for-large,td.hide-for-large,th.hide-for-large-down,td.hide-for-large-down,th.show-for-xlarge-only,td.show-for-xlarge-only,th.show-for-xlarge-up,td.show-for-xlarge-up,th.show-for-xlarge,td.show-for-xlarge,th.show-for-xlarge-down,td.show-for-xlarge-down,th.hide-for-xxlarge-only,td.hide-for-xxlarge-only,th.hide-for-xxlarge-up,td.hide-for-xxlarge-up,th.hide-for-xxlarge,td.hide-for-xxlarge,th.show-for-xxlarge-down,td.show-for-xxlarge-down{display:table-cell !important}}@media only screen and (min-width: 120.0625em){.hide-for-small-only,.show-for-small-up,.hide-for-small,.hide-for-small-down,.hide-for-medium-only,.show-for-medium-up,.hide-for-medium,.hide-for-medium-down,.hide-for-large-only,.show-for-large-up,.hide-for-large,.hide-for-large-down,.hide-for-xlarge-only,.show-for-xlarge-up,.hide-for-xlarge,.hide-for-xlarge-down,.show-for-xxlarge-only,.show-for-xxlarge-up,.show-for-xxlarge,.show-for-xxlarge-down{display:inherit !important}.show-for-small-only,.hide-for-small-up,.show-for-small,.show-for-small-down,.show-for-medium-only,.hide-for-medium-up,.show-for-medium,.show-for-medium-down,.show-for-large-only,.hide-for-large-up,.show-for-large,.show-for-large-down,.show-for-xlarge-only,.hide-for-xlarge-up,.show-for-xlarge,.show-for-xlarge-down,.hide-for-xxlarge-only,.hide-for-xxlarge-up,.hide-for-xxlarge,.hide-for-xxlarge-down{display:none !important}.hidden-for-small-only,.visible-for-small-up,.hidden-for-small,.hidden-for-small-down,.hidden-for-medium-only,.visible-for-medium-up,.hidden-for-medium,.hidden-for-medium-down,.hidden-for-large-only,.visible-for-large-up,.hidden-for-large,.hidden-for-large-down,.hidden-for-xlarge-only,.visible-for-xlarge-up,.hidden-for-xlarge,.hidden-for-xlarge-down,.visible-for-xxlarge-only,.visible-for-xxlarge-up,.visible-for-xxlarge,.visible-for-xxlarge-down{position:static !important;height:auto;width:auto;overflow:visible;clip:auto}.visible-for-small-only,.hidden-for-small-up,.visible-for-small,.visible-for-small-down,.visible-for-medium-only,.hidden-for-medium-up,.visible-for-medium,.visible-for-medium-down,.visible-for-large-only,.hidden-for-large-up,.visible-for-large,.visible-for-large-down,.visible-for-xlarge-only,.hidden-for-xlarge-up,.visible-for-xlarge,.visible-for-xlarge-down,.hidden-for-xxlarge-only,.hidden-for-xxlarge-up,.hidden-for-xxlarge,.hidden-for-xxlarge-down{position:absolute !important;height:1px;width:1px;overflow:hidden;clip:rect(1px, 1px, 1px, 1px)}table.hide-for-small-only,table.show-for-small-up,table.hide-for-small,table.hide-for-small-down,table.hide-for-medium-only,table.show-for-medium-up,table.hide-for-medium,table.hide-for-medium-down,table.hide-for-large-only,table.show-for-large-up,table.hide-for-large,table.hide-for-large-down,table.hide-for-xlarge-only,table.show-for-xlarge-up,table.hide-for-xlarge,table.hide-for-xlarge-down,table.show-for-xxlarge-only,table.show-for-xxlarge-up,table.show-for-xxlarge,table.show-for-xxlarge-down{display:table !important}thead.hide-for-small-only,thead.show-for-small-up,thead.hide-for-small,thead.hide-for-small-down,thead.hide-for-medium-only,thead.show-for-medium-up,thead.hide-for-medium,thead.hide-for-medium-down,thead.hide-for-large-only,thead.show-for-large-up,thead.hide-for-large,thead.hide-for-large-down,thead.hide-for-xlarge-only,thead.show-for-xlarge-up,thead.hide-for-xlarge,thead.hide-for-xlarge-down,thead.show-for-xxlarge-only,thead.show-for-xxlarge-up,thead.show-for-xxlarge,thead.show-for-xxlarge-down{display:table-header-group !important}tbody.hide-for-small-only,tbody.show-for-small-up,tbody.hide-for-small,tbody.hide-for-small-down,tbody.hide-for-medium-only,tbody.show-for-medium-up,tbody.hide-for-medium,tbody.hide-for-medium-down,tbody.hide-for-large-only,tbody.show-for-large-up,tbody.hide-for-large,tbody.hide-for-large-down,tbody.hide-for-xlarge-only,tbody.show-for-xlarge-up,tbody.hide-for-xlarge,tbody.hide-for-xlarge-down,tbody.show-for-xxlarge-only,tbody.show-for-xxlarge-up,tbody.show-for-xxlarge,tbody.show-for-xxlarge-down{display:table-row-group !important}tr.hide-for-small-only,tr.show-for-small-up,tr.hide-for-small,tr.hide-for-small-down,tr.hide-for-medium-only,tr.show-for-medium-up,tr.hide-for-medium,tr.hide-for-medium-down,tr.hide-for-large-only,tr.show-for-large-up,tr.hide-for-large,tr.hide-for-large-down,tr.hide-for-xlarge-only,tr.show-for-xlarge-up,tr.hide-for-xlarge,tr.hide-for-xlarge-down,tr.show-for-xxlarge-only,tr.show-for-xxlarge-up,tr.show-for-xxlarge,tr.show-for-xxlarge-down{display:table-row}th.hide-for-small-only,td.hide-for-small-only,th.show-for-small-up,td.show-for-small-up,th.hide-for-small,td.hide-for-small,th.hide-for-small-down,td.hide-for-small-down,th.hide-for-medium-only,td.hide-for-medium-only,th.show-for-medium-up,td.show-for-medium-up,th.hide-for-medium,td.hide-for-medium,th.hide-for-medium-down,td.hide-for-medium-down,th.hide-for-large-only,td.hide-for-large-only,th.show-for-large-up,td.show-for-large-up,th.hide-for-large,td.hide-for-large,th.hide-for-large-down,td.hide-for-large-down,th.hide-for-xlarge-only,td.hide-for-xlarge-only,th.show-for-xlarge-up,td.show-for-xlarge-up,th.hide-for-xlarge,td.hide-for-xlarge,th.hide-for-xlarge-down,td.hide-for-xlarge-down,th.show-for-xxlarge-only,td.show-for-xxlarge-only,th.show-for-xxlarge-up,td.show-for-xxlarge-up,th.show-for-xxlarge,td.show-for-xxlarge,th.show-for-xxlarge-down,td.show-for-xxlarge-down{display:table-cell !important}}.show-for-landscape,.hide-for-portrait{display:inherit !important}.hide-for-landscape,.show-for-portrait{display:none !important}table.hide-for-landscape,table.show-for-portrait{display:table !important}thead.hide-for-landscape,thead.show-for-portrait{display:table-header-group !important}tbody.hide-for-landscape,tbody.show-for-portrait{display:table-row-group !important}tr.hide-for-landscape,tr.show-for-portrait{display:table-row !important}td.hide-for-landscape,td.show-for-portrait,th.hide-for-landscape,th.show-for-portrait{display:table-cell !important}@media only screen and (orientation: landscape){.show-for-landscape,.hide-for-portrait{display:inherit !important}.hide-for-landscape,.show-for-portrait{display:none !important}table.show-for-landscape,table.hide-for-portrait{display:table !important}thead.show-for-landscape,thead.hide-for-portrait{display:table-header-group !important}tbody.show-for-landscape,tbody.hide-for-portrait{display:table-row-group !important}tr.show-for-landscape,tr.hide-for-portrait{display:table-row !important}td.show-for-landscape,td.hide-for-portrait,th.show-for-landscape,th.hide-for-portrait{display:table-cell !important}}@media only screen and (orientation: portrait){.show-for-portrait,.hide-for-landscape{display:inherit !important}.hide-for-portrait,.show-for-landscape{display:none !important}table.show-for-portrait,table.hide-for-landscape{display:table !important}thead.show-for-portrait,thead.hide-for-landscape{display:table-header-group !important}tbody.show-for-portrait,tbody.hide-for-landscape{display:table-row-group !important}tr.show-for-portrait,tr.hide-for-landscape{display:table-row !important}td.show-for-portrait,td.hide-for-landscape,th.show-for-portrait,th.hide-for-landscape{display:table-cell !important}}.show-for-touch{display:none !important}.hide-for-touch{display:inherit !important}.touch .show-for-touch{display:inherit !important}.touch .hide-for-touch{display:none !important}table.hide-for-touch{display:table !important}.touch table.show-for-touch{display:table !important}thead.hide-for-touch{display:table-header-group !important}.touch thead.show-for-touch{display:table-header-group !important}tbody.hide-for-touch{display:table-row-group !important}.touch tbody.show-for-touch{display:table-row-group !important}tr.hide-for-touch{display:table-row !important}.touch tr.show-for-touch{display:table-row !important}td.hide-for-touch{display:table-cell !important}.touch td.show-for-touch{display:table-cell !important}th.hide-for-touch{display:table-cell !important}.touch th.show-for-touch{display:table-cell !important}.print-only{display:none !important}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}.show-for-print{display:block}.hide-for-print{display:none}table.show-for-print{display:table !important}thead.show-for-print{display:table-header-group !important}tbody.show-for-print{display:table-row-group !important}tr.show-for-print{display:table-row !important}td.show-for-print{display:table-cell !important}th.show-for-print{display:table-cell !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}.hide-on-print{display:none !important}.print-only{display:block !important}.hide-for-print{display:none !important}.show-for-print{display:inherit !important}}@media print{.show-for-print{display:block}.hide-for-print{display:none}table.show-for-print{display:table !important}thead.show-for-print{display:table-header-group !important}tbody.show-for-print{display:table-row-group !important}tr.show-for-print{display:table-row !important}td.show-for-print{display:table-cell !important}th.show-for-print{display:table-cell !important}}.slick-slider{position:relative;display:block;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-ms-touch-action:pan-y;touch-action:pan-y;-webkit-tap-highlight-color:transparent}.slick-list{position:relative;overflow:hidden;display:block;margin:0;padding:0}.slick-list:focus{outline:none}.slick-list.dragging{cursor:pointer;cursor:hand}.slick-slider .slick-track,.slick-slider .slick-list{-webkit-transform:translate3d(0, 0, 0);-moz-transform:translate3d(0, 0, 0);-ms-transform:translate3d(0, 0, 0);-o-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0)}.slick-track{position:relative;left:0;top:0;display:block}.slick-track:before,.slick-track:after{content:"";display:table}.slick-track:after{clear:both}.slick-loading .slick-track{visibility:hidden}.slick-slide{float:left;height:100%;min-height:1px;display:none}[dir="rtl"] .slick-slide{float:right}.slick-slide img{display:block}.slick-slide.slick-loading img{display:none}.slick-slide.dragging img{pointer-events:none}.slick-initialized .slick-slide{display:block}.slick-loading .slick-slide{visibility:hidden}.slick-vertical .slick-slide{display:block;height:auto;border:1px solid transparent}.slick-loading .slick-list{background:#fff url("../img/ajax-loader.gif") center center no-repeat}.slick-prev,.slick-next{position:absolute;display:block;height:20px;width:20px;line-height:0;font-size:0;cursor:pointer;background:transparent;color:transparent;top:50%;margin-top:-10px;padding:0;border:none;outline:none}.slick-prev:hover,.slick-prev:focus,.slick-next:hover,.slick-next:focus{outline:none;background:transparent;color:transparent}.slick-prev:hover:before,.slick-prev:focus:before,.slick-next:hover:before,.slick-next:focus:before{opacity:1}.slick-prev.slick-disabled:before,.slick-next.slick-disabled:before{opacity:.25}.slick-prev:before,.slick-next:before{font-family:"FontAwesome";font-size:20px;line-height:1;color:#ba2619;opacity:.75;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.slick-prev{left:15px}[dir="rtl"] .slick-prev{left:auto;right:15px}.slick-prev:before{content:""}[dir="rtl"] .slick-prev:before{content:""}.slick-next{right:15px}[dir="rtl"] .slick-next{left:15px;right:auto}.slick-next:before{content:""}[dir="rtl"] .slick-next:before{content:""}.slick-slider{margin-bottom:30px}.slick-dots{margin:0;position:absolute;bottom:30px;list-style:none;display:block;text-align:center;padding:0;width:100%}.slick-dots li{position:relative;display:inline-block;height:20px;width:20px;margin:0 5px;padding:0;cursor:pointer}.slick-dots li button{border:0;background:transparent;display:block;height:20px;width:20px;outline:none;line-height:0;font-size:0;color:transparent;padding:5px;cursor:pointer}.slick-dots li button:hover,.slick-dots li button:focus{outline:none}.slick-dots li button:hover:before,.slick-dots li button:focus:before{opacity:1}.slick-dots li button:before{position:absolute;top:0;left:0;content:"";width:20px;height:20px;font-family:"FontAwesome";font-size:12px;line-height:20px;text-align:center;color:#000;opacity:.25;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.slick-dots li.slick-active button:before{color:#ba2619;opacity:.75}/*! +/*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}meta.foundation-version{font-family:"/5.5.1/"}meta.foundation-mq-small{font-family:"/only screen/";width:0em}meta.foundation-mq-small-only{font-family:"/only screen and (max-width: 40em)/";width:0em}meta.foundation-mq-medium{font-family:"/only screen and (min-width:40.0625em)/";width:40.0625em}meta.foundation-mq-medium-only{font-family:"/only screen and (min-width:40.0625em) and (max-width:64em)/";width:40.0625em}meta.foundation-mq-large{font-family:"/only screen and (min-width:64.0625em)/";width:64.0625em}meta.foundation-mq-large-only{font-family:"/only screen and (min-width:64.0625em) and (max-width:90em)/";width:64.0625em}meta.foundation-mq-xlarge{font-family:"/only screen and (min-width:90.0625em)/";width:90.0625em}meta.foundation-mq-xlarge-only{font-family:"/only screen and (min-width:90.0625em) and (max-width:120em)/";width:90.0625em}meta.foundation-mq-xxlarge{font-family:"/only screen and (min-width:120.0625em)/";width:120.0625em}meta.foundation-data-attribute-namespace{font-family:false}html,body{height:100%}*,*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html,body{font-size:100%}body{background:#fff;color:#222;padding:0;margin:0;font-family:"Open Sans","Helvetica Neue",Helvetica,Roboto,Arial,sans-serif;font-weight:400;font-style:normal;line-height:1.5;position:relative;cursor:auto}a:hover{cursor:pointer}img{max-width:100%;height:auto}img{-ms-interpolation-mode:bicubic}#map_canvas img,#map_canvas embed,#map_canvas object,.map_canvas img,.map_canvas embed,.map_canvas object{max-width:none !important}.left{float:left !important}.right{float:right !important}.clearfix:before,.clearfix:after{content:" ";display:table}.clearfix:after{clear:both}.hide{display:none}.invisible{visibility:hidden}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}img{display:inline-block;vertical-align:middle}textarea{height:auto;min-height:50px}select{width:100%}[class*="block-grid-"]{display:block;padding:0;margin:0 -.625rem}[class*="block-grid-"]:before,[class*="block-grid-"]:after{content:" ";display:table}[class*="block-grid-"]:after{clear:both}[class*="block-grid-"]>li{display:block;height:auto;float:left;padding:0 .625rem 1.25rem}@media only screen{.small-block-grid-1>li{width:100%;list-style:none}.small-block-grid-1>li:nth-of-type(1n){clear:none}.small-block-grid-1>li:nth-of-type(1n+1){clear:both}.small-block-grid-2>li{width:50%;list-style:none}.small-block-grid-2>li:nth-of-type(1n){clear:none}.small-block-grid-2>li:nth-of-type(2n+1){clear:both}.small-block-grid-3>li{width:33.3333333333%;list-style:none}.small-block-grid-3>li:nth-of-type(1n){clear:none}.small-block-grid-3>li:nth-of-type(3n+1){clear:both}.small-block-grid-4>li{width:25%;list-style:none}.small-block-grid-4>li:nth-of-type(1n){clear:none}.small-block-grid-4>li:nth-of-type(4n+1){clear:both}.small-block-grid-5>li{width:20%;list-style:none}.small-block-grid-5>li:nth-of-type(1n){clear:none}.small-block-grid-5>li:nth-of-type(5n+1){clear:both}.small-block-grid-6>li{width:16.6666666667%;list-style:none}.small-block-grid-6>li:nth-of-type(1n){clear:none}.small-block-grid-6>li:nth-of-type(6n+1){clear:both}.small-block-grid-7>li{width:14.2857142857%;list-style:none}.small-block-grid-7>li:nth-of-type(1n){clear:none}.small-block-grid-7>li:nth-of-type(7n+1){clear:both}.small-block-grid-8>li{width:12.5%;list-style:none}.small-block-grid-8>li:nth-of-type(1n){clear:none}.small-block-grid-8>li:nth-of-type(8n+1){clear:both}.small-block-grid-9>li{width:11.1111111111%;list-style:none}.small-block-grid-9>li:nth-of-type(1n){clear:none}.small-block-grid-9>li:nth-of-type(9n+1){clear:both}.small-block-grid-10>li{width:10%;list-style:none}.small-block-grid-10>li:nth-of-type(1n){clear:none}.small-block-grid-10>li:nth-of-type(10n+1){clear:both}.small-block-grid-11>li{width:9.0909090909%;list-style:none}.small-block-grid-11>li:nth-of-type(1n){clear:none}.small-block-grid-11>li:nth-of-type(11n+1){clear:both}.small-block-grid-12>li{width:8.3333333333%;list-style:none}.small-block-grid-12>li:nth-of-type(1n){clear:none}.small-block-grid-12>li:nth-of-type(12n+1){clear:both}}@media only screen and (min-width: 40.0625em){.medium-block-grid-1>li{width:100%;list-style:none}.medium-block-grid-1>li:nth-of-type(1n){clear:none}.medium-block-grid-1>li:nth-of-type(1n+1){clear:both}.medium-block-grid-2>li{width:50%;list-style:none}.medium-block-grid-2>li:nth-of-type(1n){clear:none}.medium-block-grid-2>li:nth-of-type(2n+1){clear:both}.medium-block-grid-3>li{width:33.3333333333%;list-style:none}.medium-block-grid-3>li:nth-of-type(1n){clear:none}.medium-block-grid-3>li:nth-of-type(3n+1){clear:both}.medium-block-grid-4>li{width:25%;list-style:none}.medium-block-grid-4>li:nth-of-type(1n){clear:none}.medium-block-grid-4>li:nth-of-type(4n+1){clear:both}.medium-block-grid-5>li{width:20%;list-style:none}.medium-block-grid-5>li:nth-of-type(1n){clear:none}.medium-block-grid-5>li:nth-of-type(5n+1){clear:both}.medium-block-grid-6>li{width:16.6666666667%;list-style:none}.medium-block-grid-6>li:nth-of-type(1n){clear:none}.medium-block-grid-6>li:nth-of-type(6n+1){clear:both}.medium-block-grid-7>li{width:14.2857142857%;list-style:none}.medium-block-grid-7>li:nth-of-type(1n){clear:none}.medium-block-grid-7>li:nth-of-type(7n+1){clear:both}.medium-block-grid-8>li{width:12.5%;list-style:none}.medium-block-grid-8>li:nth-of-type(1n){clear:none}.medium-block-grid-8>li:nth-of-type(8n+1){clear:both}.medium-block-grid-9>li{width:11.1111111111%;list-style:none}.medium-block-grid-9>li:nth-of-type(1n){clear:none}.medium-block-grid-9>li:nth-of-type(9n+1){clear:both}.medium-block-grid-10>li{width:10%;list-style:none}.medium-block-grid-10>li:nth-of-type(1n){clear:none}.medium-block-grid-10>li:nth-of-type(10n+1){clear:both}.medium-block-grid-11>li{width:9.0909090909%;list-style:none}.medium-block-grid-11>li:nth-of-type(1n){clear:none}.medium-block-grid-11>li:nth-of-type(11n+1){clear:both}.medium-block-grid-12>li{width:8.3333333333%;list-style:none}.medium-block-grid-12>li:nth-of-type(1n){clear:none}.medium-block-grid-12>li:nth-of-type(12n+1){clear:both}}@media only screen and (min-width: 64.0625em){.large-block-grid-1>li{width:100%;list-style:none}.large-block-grid-1>li:nth-of-type(1n){clear:none}.large-block-grid-1>li:nth-of-type(1n+1){clear:both}.large-block-grid-2>li{width:50%;list-style:none}.large-block-grid-2>li:nth-of-type(1n){clear:none}.large-block-grid-2>li:nth-of-type(2n+1){clear:both}.large-block-grid-3>li{width:33.3333333333%;list-style:none}.large-block-grid-3>li:nth-of-type(1n){clear:none}.large-block-grid-3>li:nth-of-type(3n+1){clear:both}.large-block-grid-4>li{width:25%;list-style:none}.large-block-grid-4>li:nth-of-type(1n){clear:none}.large-block-grid-4>li:nth-of-type(4n+1){clear:both}.large-block-grid-5>li{width:20%;list-style:none}.large-block-grid-5>li:nth-of-type(1n){clear:none}.large-block-grid-5>li:nth-of-type(5n+1){clear:both}.large-block-grid-6>li{width:16.6666666667%;list-style:none}.large-block-grid-6>li:nth-of-type(1n){clear:none}.large-block-grid-6>li:nth-of-type(6n+1){clear:both}.large-block-grid-7>li{width:14.2857142857%;list-style:none}.large-block-grid-7>li:nth-of-type(1n){clear:none}.large-block-grid-7>li:nth-of-type(7n+1){clear:both}.large-block-grid-8>li{width:12.5%;list-style:none}.large-block-grid-8>li:nth-of-type(1n){clear:none}.large-block-grid-8>li:nth-of-type(8n+1){clear:both}.large-block-grid-9>li{width:11.1111111111%;list-style:none}.large-block-grid-9>li:nth-of-type(1n){clear:none}.large-block-grid-9>li:nth-of-type(9n+1){clear:both}.large-block-grid-10>li{width:10%;list-style:none}.large-block-grid-10>li:nth-of-type(1n){clear:none}.large-block-grid-10>li:nth-of-type(10n+1){clear:both}.large-block-grid-11>li{width:9.0909090909%;list-style:none}.large-block-grid-11>li:nth-of-type(1n){clear:none}.large-block-grid-11>li:nth-of-type(11n+1){clear:both}.large-block-grid-12>li{width:8.3333333333%;list-style:none}.large-block-grid-12>li:nth-of-type(1n){clear:none}.large-block-grid-12>li:nth-of-type(12n+1){clear:both}}button,.button{border-style:solid;border-width:0;cursor:pointer;font-family:"Open Sans","Helvetica Neue",Helvetica,Roboto,Arial,sans-serif;font-weight:400;line-height:normal;margin:0 0 1.25rem;position:relative;text-decoration:none;text-align:center;-webkit-appearance:none;-moz-appearance:none;border-radius:0;display:inline-block;padding-top:1rem;padding-right:2rem;padding-bottom:1.0625rem;padding-left:2rem;font-size:1rem;background-color:#ba2619;border-color:#951e14;color:#fff;transition:background-color 300ms ease-out}button:hover,button:focus,.button:hover,.button:focus{background-color:#951e14}button:hover,button:focus,.button:hover,.button:focus{color:#fff}button.secondary,.button.secondary{background-color:#e7e7e7;border-color:#b9b9b9;color:#333}button.secondary:hover,button.secondary:focus,.button.secondary:hover,.button.secondary:focus{background-color:#b9b9b9}button.secondary:hover,button.secondary:focus,.button.secondary:hover,.button.secondary:focus{color:#333}button.success,.button.success{background-color:#43AC6A;border-color:#368a55;color:#fff}button.success:hover,button.success:focus,.button.success:hover,.button.success:focus{background-color:#368a55}button.success:hover,button.success:focus,.button.success:hover,.button.success:focus{color:#fff}button.alert,.button.alert{background-color:#f04124;border-color:#cf2a0e;color:#fff}button.alert:hover,button.alert:focus,.button.alert:hover,.button.alert:focus{background-color:#cf2a0e}button.alert:hover,button.alert:focus,.button.alert:hover,.button.alert:focus{color:#fff}button.warning,.button.warning{background-color:#f08a24;border-color:#cf6e0e;color:#fff}button.warning:hover,button.warning:focus,.button.warning:hover,.button.warning:focus{background-color:#cf6e0e}button.warning:hover,button.warning:focus,.button.warning:hover,.button.warning:focus{color:#fff}button.info,.button.info{background-color:#a0d3e8;border-color:#61b6d9;color:#333}button.info:hover,button.info:focus,.button.info:hover,.button.info:focus{background-color:#61b6d9}button.info:hover,button.info:focus,.button.info:hover,.button.info:focus{color:#fff}button.large,.button.large{padding-top:1.125rem;padding-right:2.25rem;padding-bottom:1.1875rem;padding-left:2.25rem;font-size:1.25rem}button.small,.button.small{padding-top:.875rem;padding-right:1.75rem;padding-bottom:.9375rem;padding-left:1.75rem;font-size:.8125rem}button.tiny,.button.tiny{padding-top:.625rem;padding-right:1.25rem;padding-bottom:.6875rem;padding-left:1.25rem;font-size:.6875rem}button.expand,.button.expand{padding-right:0;padding-left:0;width:100%}button.left-align,.button.left-align{text-align:left;text-indent:.75rem}button.right-align,.button.right-align{text-align:right;padding-right:.75rem}button.radius,.button.radius{border-radius:3px}button.round,.button.round{border-radius:1000px}button.disabled,button[disabled],.button.disabled,.button[disabled]{background-color:#ba2619;border-color:#951e14;color:#fff;cursor:default;opacity:.7;box-shadow:none}button.disabled:hover,button.disabled:focus,button[disabled]:hover,button[disabled]:focus,.button.disabled:hover,.button.disabled:focus,.button[disabled]:hover,.button[disabled]:focus{background-color:#951e14}button.disabled:hover,button.disabled:focus,button[disabled]:hover,button[disabled]:focus,.button.disabled:hover,.button.disabled:focus,.button[disabled]:hover,.button[disabled]:focus{color:#fff}button.disabled:hover,button.disabled:focus,button[disabled]:hover,button[disabled]:focus,.button.disabled:hover,.button.disabled:focus,.button[disabled]:hover,.button[disabled]:focus{background-color:#ba2619}button.disabled.secondary,button[disabled].secondary,.button.disabled.secondary,.button[disabled].secondary{background-color:#e7e7e7;border-color:#b9b9b9;color:#333;cursor:default;opacity:.7;box-shadow:none}button.disabled.secondary:hover,button.disabled.secondary:focus,button[disabled].secondary:hover,button[disabled].secondary:focus,.button.disabled.secondary:hover,.button.disabled.secondary:focus,.button[disabled].secondary:hover,.button[disabled].secondary:focus{background-color:#b9b9b9}button.disabled.secondary:hover,button.disabled.secondary:focus,button[disabled].secondary:hover,button[disabled].secondary:focus,.button.disabled.secondary:hover,.button.disabled.secondary:focus,.button[disabled].secondary:hover,.button[disabled].secondary:focus{color:#333}button.disabled.secondary:hover,button.disabled.secondary:focus,button[disabled].secondary:hover,button[disabled].secondary:focus,.button.disabled.secondary:hover,.button.disabled.secondary:focus,.button[disabled].secondary:hover,.button[disabled].secondary:focus{background-color:#e7e7e7}button.disabled.success,button[disabled].success,.button.disabled.success,.button[disabled].success{background-color:#43AC6A;border-color:#368a55;color:#fff;cursor:default;opacity:.7;box-shadow:none}button.disabled.success:hover,button.disabled.success:focus,button[disabled].success:hover,button[disabled].success:focus,.button.disabled.success:hover,.button.disabled.success:focus,.button[disabled].success:hover,.button[disabled].success:focus{background-color:#368a55}button.disabled.success:hover,button.disabled.success:focus,button[disabled].success:hover,button[disabled].success:focus,.button.disabled.success:hover,.button.disabled.success:focus,.button[disabled].success:hover,.button[disabled].success:focus{color:#fff}button.disabled.success:hover,button.disabled.success:focus,button[disabled].success:hover,button[disabled].success:focus,.button.disabled.success:hover,.button.disabled.success:focus,.button[disabled].success:hover,.button[disabled].success:focus{background-color:#43AC6A}button.disabled.alert,button[disabled].alert,.button.disabled.alert,.button[disabled].alert{background-color:#f04124;border-color:#cf2a0e;color:#fff;cursor:default;opacity:.7;box-shadow:none}button.disabled.alert:hover,button.disabled.alert:focus,button[disabled].alert:hover,button[disabled].alert:focus,.button.disabled.alert:hover,.button.disabled.alert:focus,.button[disabled].alert:hover,.button[disabled].alert:focus{background-color:#cf2a0e}button.disabled.alert:hover,button.disabled.alert:focus,button[disabled].alert:hover,button[disabled].alert:focus,.button.disabled.alert:hover,.button.disabled.alert:focus,.button[disabled].alert:hover,.button[disabled].alert:focus{color:#fff}button.disabled.alert:hover,button.disabled.alert:focus,button[disabled].alert:hover,button[disabled].alert:focus,.button.disabled.alert:hover,.button.disabled.alert:focus,.button[disabled].alert:hover,.button[disabled].alert:focus{background-color:#f04124}button.disabled.warning,button[disabled].warning,.button.disabled.warning,.button[disabled].warning{background-color:#f08a24;border-color:#cf6e0e;color:#fff;cursor:default;opacity:.7;box-shadow:none}button.disabled.warning:hover,button.disabled.warning:focus,button[disabled].warning:hover,button[disabled].warning:focus,.button.disabled.warning:hover,.button.disabled.warning:focus,.button[disabled].warning:hover,.button[disabled].warning:focus{background-color:#cf6e0e}button.disabled.warning:hover,button.disabled.warning:focus,button[disabled].warning:hover,button[disabled].warning:focus,.button.disabled.warning:hover,.button.disabled.warning:focus,.button[disabled].warning:hover,.button[disabled].warning:focus{color:#fff}button.disabled.warning:hover,button.disabled.warning:focus,button[disabled].warning:hover,button[disabled].warning:focus,.button.disabled.warning:hover,.button.disabled.warning:focus,.button[disabled].warning:hover,.button[disabled].warning:focus{background-color:#f08a24}button.disabled.info,button[disabled].info,.button.disabled.info,.button[disabled].info{background-color:#a0d3e8;border-color:#61b6d9;color:#333;cursor:default;opacity:.7;box-shadow:none}button.disabled.info:hover,button.disabled.info:focus,button[disabled].info:hover,button[disabled].info:focus,.button.disabled.info:hover,.button.disabled.info:focus,.button[disabled].info:hover,.button[disabled].info:focus{background-color:#61b6d9}button.disabled.info:hover,button.disabled.info:focus,button[disabled].info:hover,button[disabled].info:focus,.button.disabled.info:hover,.button.disabled.info:focus,.button[disabled].info:hover,.button[disabled].info:focus{color:#fff}button.disabled.info:hover,button.disabled.info:focus,button[disabled].info:hover,button[disabled].info:focus,.button.disabled.info:hover,.button.disabled.info:focus,.button[disabled].info:hover,.button[disabled].info:focus{background-color:#a0d3e8}button::-moz-focus-inner{border:0;padding:0}@media only screen and (min-width: 40.0625em){button,.button{display:inline-block}}.clearing-thumbs,[data-clearing]{margin-bottom:0;margin-left:0;list-style:none}.clearing-thumbs:before,.clearing-thumbs:after,[data-clearing]:before,[data-clearing]:after{content:" ";display:table}.clearing-thumbs:after,[data-clearing]:after{clear:both}.clearing-thumbs li,[data-clearing] li{float:left;margin-right:10px}.clearing-thumbs[class*="block-grid-"] li,[data-clearing][class*="block-grid-"] li{margin-right:0}.clearing-blackout{background:#333;position:fixed;width:100%;height:100%;top:0;left:0;z-index:998}.clearing-blackout .clearing-close{display:block}.clearing-container{position:relative;z-index:998;height:100%;overflow:hidden;margin:0}.clearing-touch-label{position:absolute;top:50%;left:50%;color:#aaa;font-size:0.6em}.visible-img{height:95%;position:relative}.visible-img img{position:absolute;left:50%;top:50%;transform:translateY(-50%) translateX(-50%);-webkit-transform:translateY(-50%) translateX(-50%);-ms-transform:translateY(-50%) translateX(-50%);max-height:100%;max-width:100%}.clearing-caption{color:#ccc;font-size:.875em;line-height:1.3;margin-bottom:0;text-align:center;bottom:0;background:#333;width:100%;padding:10px 30px 20px;position:absolute;left:0}.clearing-close{z-index:999;padding-left:20px;padding-top:10px;font-size:30px;line-height:1;color:#ccc;display:none}.clearing-close:hover,.clearing-close:focus{color:#ccc}.clearing-assembled .clearing-container{height:100%}.clearing-assembled .clearing-container .carousel>ul{display:none}.clearing-feature li{display:none}.clearing-feature li.clearing-featured-img{display:block}@media only screen and (min-width: 40.0625em){.clearing-main-prev,.clearing-main-next{position:absolute;height:100%;width:40px;top:0}.clearing-main-prev>span,.clearing-main-next>span{position:absolute;top:50%;display:block;width:0;height:0;border:solid 12px}.clearing-main-prev>span:hover,.clearing-main-next>span:hover{opacity:0.8}.clearing-main-prev{left:0}.clearing-main-prev>span{left:5px;border-color:transparent;border-right-color:#ccc}.clearing-main-next{right:0}.clearing-main-next>span{border-color:transparent;border-left-color:#ccc}.clearing-main-prev.disabled,.clearing-main-next.disabled{opacity:0.3}.clearing-assembled .clearing-container .carousel{background:rgba(51,51,51,0.8);height:120px;margin-top:10px;text-align:center}.clearing-assembled .clearing-container .carousel>ul{display:inline-block;z-index:999;height:100%;position:relative;float:none}.clearing-assembled .clearing-container .carousel>ul li{display:block;width:120px;min-height:inherit;float:left;overflow:hidden;margin-right:0;padding:0;position:relative;cursor:pointer;opacity:0.4;clear:none}.clearing-assembled .clearing-container .carousel>ul li.fix-height img{height:100%;max-width:none}.clearing-assembled .clearing-container .carousel>ul li a.th{border:none;box-shadow:none;display:block}.clearing-assembled .clearing-container .carousel>ul li img{cursor:pointer !important;width:100% !important}.clearing-assembled .clearing-container .carousel>ul li.visible{opacity:1}.clearing-assembled .clearing-container .carousel>ul li:hover{opacity:0.8}.clearing-assembled .clearing-container .visible-img{background:#333;overflow:hidden;height:85%}.clearing-close{position:absolute;top:10px;right:20px;padding-left:0;padding-top:0}}form{margin:0 0 1rem}form .row .row{margin:0 -.5rem}form .row .row .column,form .row .row .columns{padding:0 .5rem}form .row .row.collapse{margin:0}form .row .row.collapse .column,form .row .row.collapse .columns{padding:0}form .row .row.collapse input{-webkit-border-bottom-right-radius:0;-webkit-border-top-right-radius:0;border-bottom-right-radius:0;border-top-right-radius:0}form .row input.column,form .row input.columns,form .row textarea.column,form .row textarea.columns{padding-left:.5rem}label{font-size:.875rem;color:#4d4c4c;cursor:pointer;display:block;font-weight:400;line-height:1.5;margin-bottom:0}label.right{float:none !important;text-align:right}label.inline{margin:0 0 1rem 0;padding:.5625rem 0}label small{text-transform:capitalize;color:#676767}.prefix,.postfix{display:block;position:relative;z-index:2;text-align:center;width:100%;padding-top:0;padding-bottom:0;border-style:solid;border-width:1px;overflow:visible;font-size:.875rem;height:2.3125rem;line-height:2.3125rem}.postfix.button{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;text-align:center;border:none}.prefix.button{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;text-align:center;border:none}.prefix.button.radius{border-radius:0;-webkit-border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-bottom-left-radius:3px;border-top-left-radius:3px}.postfix.button.radius{border-radius:0;-webkit-border-bottom-right-radius:3px;-webkit-border-top-right-radius:3px;border-bottom-right-radius:3px;border-top-right-radius:3px}.prefix.button.round{border-radius:0;-webkit-border-bottom-left-radius:1000px;-webkit-border-top-left-radius:1000px;border-bottom-left-radius:1000px;border-top-left-radius:1000px}.postfix.button.round{border-radius:0;-webkit-border-bottom-right-radius:1000px;-webkit-border-top-right-radius:1000px;border-bottom-right-radius:1000px;border-top-right-radius:1000px}span.prefix,label.prefix{background:#f2f2f2;border-right:none;color:#333;border-color:#ccc}span.postfix,label.postfix{background:#f2f2f2;border-left:none;color:#333;border-color:#ccc}input[type="text"],input[type="password"],input[type="date"],input[type="datetime"],input[type="datetime-local"],input[type="month"],input[type="week"],input[type="email"],input[type="number"],input[type="search"],input[type="tel"],input[type="time"],input[type="url"],input[type="color"],textarea{-webkit-appearance:none;border-radius:0;background-color:#fff;font-family:inherit;border-style:solid;border-width:1px;border-color:#ccc;box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);color:rgba(0,0,0,0.75);display:block;font-size:.875rem;margin:0 0 1rem 0;padding:.5rem;height:2.3125rem;width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;transition:all .15s linear}input[type="text"]:focus,input[type="password"]:focus,input[type="date"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="month"]:focus,input[type="week"]:focus,input[type="email"]:focus,input[type="number"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="time"]:focus,input[type="url"]:focus,input[type="color"]:focus,textarea:focus{background:#fafafa;border-color:#999;outline:none}input[type="text"]:disabled,input[type="password"]:disabled,input[type="date"]:disabled,input[type="datetime"]:disabled,input[type="datetime-local"]:disabled,input[type="month"]:disabled,input[type="week"]:disabled,input[type="email"]:disabled,input[type="number"]:disabled,input[type="search"]:disabled,input[type="tel"]:disabled,input[type="time"]:disabled,input[type="url"]:disabled,input[type="color"]:disabled,textarea:disabled{background-color:#ddd;cursor:default}input[type="text"][disabled],input[type="text"][readonly],fieldset[disabled] input[type="text"],input[type="password"][disabled],input[type="password"][readonly],fieldset[disabled] input[type="password"],input[type="date"][disabled],input[type="date"][readonly],fieldset[disabled] input[type="date"],input[type="datetime"][disabled],input[type="datetime"][readonly],fieldset[disabled] input[type="datetime"],input[type="datetime-local"][disabled],input[type="datetime-local"][readonly],fieldset[disabled] input[type="datetime-local"],input[type="month"][disabled],input[type="month"][readonly],fieldset[disabled] input[type="month"],input[type="week"][disabled],input[type="week"][readonly],fieldset[disabled] input[type="week"],input[type="email"][disabled],input[type="email"][readonly],fieldset[disabled] input[type="email"],input[type="number"][disabled],input[type="number"][readonly],fieldset[disabled] input[type="number"],input[type="search"][disabled],input[type="search"][readonly],fieldset[disabled] input[type="search"],input[type="tel"][disabled],input[type="tel"][readonly],fieldset[disabled] input[type="tel"],input[type="time"][disabled],input[type="time"][readonly],fieldset[disabled] input[type="time"],input[type="url"][disabled],input[type="url"][readonly],fieldset[disabled] input[type="url"],input[type="color"][disabled],input[type="color"][readonly],fieldset[disabled] input[type="color"],textarea[disabled],textarea[readonly],fieldset[disabled] textarea{background-color:#ddd;cursor:default}input[type="text"].radius,input[type="password"].radius,input[type="date"].radius,input[type="datetime"].radius,input[type="datetime-local"].radius,input[type="month"].radius,input[type="week"].radius,input[type="email"].radius,input[type="number"].radius,input[type="search"].radius,input[type="tel"].radius,input[type="time"].radius,input[type="url"].radius,input[type="color"].radius,textarea.radius{border-radius:3px}form .row .prefix-radius.row.collapse input,form .row .prefix-radius.row.collapse textarea,form .row .prefix-radius.row.collapse select,form .row .prefix-radius.row.collapse button{border-radius:0;-webkit-border-bottom-right-radius:3px;-webkit-border-top-right-radius:3px;border-bottom-right-radius:3px;border-top-right-radius:3px}form .row .prefix-radius.row.collapse .prefix{border-radius:0;-webkit-border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-bottom-left-radius:3px;border-top-left-radius:3px}form .row .postfix-radius.row.collapse input,form .row .postfix-radius.row.collapse textarea,form .row .postfix-radius.row.collapse select,form .row .postfix-radius.row.collapse button{border-radius:0;-webkit-border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-bottom-left-radius:3px;border-top-left-radius:3px}form .row .postfix-radius.row.collapse .postfix{border-radius:0;-webkit-border-bottom-right-radius:3px;-webkit-border-top-right-radius:3px;border-bottom-right-radius:3px;border-top-right-radius:3px}form .row .prefix-round.row.collapse input,form .row .prefix-round.row.collapse textarea,form .row .prefix-round.row.collapse select,form .row .prefix-round.row.collapse button{border-radius:0;-webkit-border-bottom-right-radius:1000px;-webkit-border-top-right-radius:1000px;border-bottom-right-radius:1000px;border-top-right-radius:1000px}form .row .prefix-round.row.collapse .prefix{border-radius:0;-webkit-border-bottom-left-radius:1000px;-webkit-border-top-left-radius:1000px;border-bottom-left-radius:1000px;border-top-left-radius:1000px}form .row .postfix-round.row.collapse input,form .row .postfix-round.row.collapse textarea,form .row .postfix-round.row.collapse select,form .row .postfix-round.row.collapse button{border-radius:0;-webkit-border-bottom-left-radius:1000px;-webkit-border-top-left-radius:1000px;border-bottom-left-radius:1000px;border-top-left-radius:1000px}form .row .postfix-round.row.collapse .postfix{border-radius:0;-webkit-border-bottom-right-radius:1000px;-webkit-border-top-right-radius:1000px;border-bottom-right-radius:1000px;border-top-right-radius:1000px}input[type="submit"]{-webkit-appearance:none;border-radius:0}textarea[rows]{height:auto}textarea{max-width:100%}select{-webkit-appearance:none !important;border-radius:0;background-color:#FAFAFA;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgeD0iMTJweCIgeT0iMHB4IiB3aWR0aD0iMjRweCIgaGVpZ2h0PSIzcHgiIHZpZXdCb3g9IjAgMCA2IDMiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDYgMyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBvbHlnb24gcG9pbnRzPSI1Ljk5MiwwIDIuOTkyLDMgLTAuMDA4LDAgIi8+PC9zdmc+);background-position:100% center;background-repeat:no-repeat;border-style:solid;border-width:1px;border-color:#ccc;padding:.5rem;font-size:.875rem;font-family:"Open Sans","Helvetica Neue",Helvetica,Roboto,Arial,sans-serif;color:rgba(0,0,0,0.75);line-height:normal;border-radius:0;height:2.3125rem}select::-ms-expand{display:none}select.radius{border-radius:3px}select:hover{background-color:#f3f2f2;border-color:#999}select:disabled{background-color:#ddd;cursor:default}select[multiple]{height:auto}input[type="file"],input[type="checkbox"],input[type="radio"],select{margin:0 0 1rem 0}input[type="checkbox"]+label,input[type="radio"]+label{display:inline-block;margin-left:.5rem;margin-right:1rem;margin-bottom:0;vertical-align:baseline}input[type="file"]{width:100%}fieldset{border:1px solid #ddd;padding:1.25rem;margin:1.125rem 0}fieldset legend{font-weight:700;background:#fff;padding:0 .1875rem;margin:0;margin-left:-.1875rem}[data-abide] .error small.error,[data-abide] .error span.error,[data-abide] span.error,[data-abide] small.error{display:block;padding:.375rem .5625rem .5625rem;margin-top:-1px;margin-bottom:1rem;font-size:.75rem;font-weight:400;font-style:italic;background:#f04124;color:#fff}[data-abide] span.error,[data-abide] small.error{display:none}span.error,small.error{display:block;padding:.375rem .5625rem .5625rem;margin-top:-1px;margin-bottom:1rem;font-size:.75rem;font-weight:400;font-style:italic;background:#f04124;color:#fff}.error input,.error textarea,.error select{margin-bottom:0}.error input[type="checkbox"],.error input[type="radio"]{margin-bottom:1rem}.error label,.error label.error{color:#f04124}.error small.error{display:block;padding:.375rem .5625rem .5625rem;margin-top:-1px;margin-bottom:1rem;font-size:.75rem;font-weight:400;font-style:italic;background:#f04124;color:#fff}.error>label>small{color:#676767;background:transparent;padding:0;text-transform:capitalize;font-style:normal;font-size:60%;margin:0;display:inline}.error span.error-message{display:block}input.error,textarea.error,select.error{margin-bottom:0}label.error{color:#f04124}.row{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5rem}.row:before,.row:after{content:" ";display:table}.row:after{clear:both}.row.collapse>.column,.row.collapse>.columns{padding-left:0;padding-right:0}.row.collapse .row{margin-left:0;margin-right:0}.row .row{width:auto;margin-left:-.9375rem;margin-right:-.9375rem;margin-top:0;margin-bottom:0;max-width:none}.row .row:before,.row .row:after{content:" ";display:table}.row .row:after{clear:both}.row .row.collapse{width:auto;margin:0;max-width:none}.row .row.collapse:before,.row .row.collapse:after{content:" ";display:table}.row .row.collapse:after{clear:both}.column,.columns{padding-left:.9375rem;padding-right:.9375rem;width:100%;float:left}[class*="column"]+[class*="column"]:last-child{float:right}[class*="column"]+[class*="column"].end{float:left}@media only screen{.small-push-0{position:relative;left:0%;right:auto}.small-pull-0{position:relative;right:0%;left:auto}.small-push-1{position:relative;left:8.3333333333%;right:auto}.small-pull-1{position:relative;right:8.3333333333%;left:auto}.small-push-2{position:relative;left:16.6666666667%;right:auto}.small-pull-2{position:relative;right:16.6666666667%;left:auto}.small-push-3{position:relative;left:25%;right:auto}.small-pull-3{position:relative;right:25%;left:auto}.small-push-4{position:relative;left:33.3333333333%;right:auto}.small-pull-4{position:relative;right:33.3333333333%;left:auto}.small-push-5{position:relative;left:41.6666666667%;right:auto}.small-pull-5{position:relative;right:41.6666666667%;left:auto}.small-push-6{position:relative;left:50%;right:auto}.small-pull-6{position:relative;right:50%;left:auto}.small-push-7{position:relative;left:58.3333333333%;right:auto}.small-pull-7{position:relative;right:58.3333333333%;left:auto}.small-push-8{position:relative;left:66.6666666667%;right:auto}.small-pull-8{position:relative;right:66.6666666667%;left:auto}.small-push-9{position:relative;left:75%;right:auto}.small-pull-9{position:relative;right:75%;left:auto}.small-push-10{position:relative;left:83.3333333333%;right:auto}.small-pull-10{position:relative;right:83.3333333333%;left:auto}.small-push-11{position:relative;left:91.6666666667%;right:auto}.small-pull-11{position:relative;right:91.6666666667%;left:auto}.column,.columns{position:relative;padding-left:.9375rem;padding-right:.9375rem;float:left}.small-1{width:8.3333333333%}.small-2{width:16.6666666667%}.small-3{width:25%}.small-4{width:33.3333333333%}.small-5{width:41.6666666667%}.small-6{width:50%}.small-7{width:58.3333333333%}.small-8{width:66.6666666667%}.small-9{width:75%}.small-10{width:83.3333333333%}.small-11{width:91.6666666667%}.small-12{width:100%}.small-offset-0{margin-left:0% !important}.small-offset-1{margin-left:8.3333333333% !important}.small-offset-2{margin-left:16.6666666667% !important}.small-offset-3{margin-left:25% !important}.small-offset-4{margin-left:33.3333333333% !important}.small-offset-5{margin-left:41.6666666667% !important}.small-offset-6{margin-left:50% !important}.small-offset-7{margin-left:58.3333333333% !important}.small-offset-8{margin-left:66.6666666667% !important}.small-offset-9{margin-left:75% !important}.small-offset-10{margin-left:83.3333333333% !important}.small-offset-11{margin-left:91.6666666667% !important}.small-reset-order{margin-left:0;margin-right:0;left:auto;right:auto;float:left}.column.small-centered,.columns.small-centered{margin-left:auto;margin-right:auto;float:none}.column.small-uncentered,.columns.small-uncentered{margin-left:0;margin-right:0;float:left}.column.small-centered:last-child,.columns.small-centered:last-child{float:none}.column.small-uncentered:last-child,.columns.small-uncentered:last-child{float:left}.column.small-uncentered.opposite,.columns.small-uncentered.opposite{float:right}.row.small-collapse>.column,.row.small-collapse>.columns{padding-left:0;padding-right:0}.row.small-collapse .row{margin-left:0;margin-right:0}.row.small-uncollapse>.column,.row.small-uncollapse>.columns{padding-left:.9375rem;padding-right:.9375rem;float:left}}@media only screen and (min-width: 40.0625em){.medium-push-0{position:relative;left:0%;right:auto}.medium-pull-0{position:relative;right:0%;left:auto}.medium-push-1{position:relative;left:8.3333333333%;right:auto}.medium-pull-1{position:relative;right:8.3333333333%;left:auto}.medium-push-2{position:relative;left:16.6666666667%;right:auto}.medium-pull-2{position:relative;right:16.6666666667%;left:auto}.medium-push-3{position:relative;left:25%;right:auto}.medium-pull-3{position:relative;right:25%;left:auto}.medium-push-4{position:relative;left:33.3333333333%;right:auto}.medium-pull-4{position:relative;right:33.3333333333%;left:auto}.medium-push-5{position:relative;left:41.6666666667%;right:auto}.medium-pull-5{position:relative;right:41.6666666667%;left:auto}.medium-push-6{position:relative;left:50%;right:auto}.medium-pull-6{position:relative;right:50%;left:auto}.medium-push-7{position:relative;left:58.3333333333%;right:auto}.medium-pull-7{position:relative;right:58.3333333333%;left:auto}.medium-push-8{position:relative;left:66.6666666667%;right:auto}.medium-pull-8{position:relative;right:66.6666666667%;left:auto}.medium-push-9{position:relative;left:75%;right:auto}.medium-pull-9{position:relative;right:75%;left:auto}.medium-push-10{position:relative;left:83.3333333333%;right:auto}.medium-pull-10{position:relative;right:83.3333333333%;left:auto}.medium-push-11{position:relative;left:91.6666666667%;right:auto}.medium-pull-11{position:relative;right:91.6666666667%;left:auto}.column,.columns{position:relative;padding-left:.9375rem;padding-right:.9375rem;float:left}.medium-1{width:8.3333333333%}.medium-3{width:25%}.medium-4{width:33.3333333333%}.medium-5{width:41.6666666667%}.medium-6{width:50%}.medium-7{width:58.3333333333%}.medium-8{width:66.6666666667%}.medium-9{width:75%}.medium-10{width:83.3333333333%}.medium-11{width:91.6666666667%}.medium-12{width:100%}.medium-offset-0{margin-left:0% !important}.medium-offset-1{margin-left:8.3333333333% !important}.medium-offset-2{margin-left:16.6666666667% !important}.medium-offset-3{margin-left:25% !important}.medium-offset-4{margin-left:33.3333333333% !important}.medium-offset-5{margin-left:41.6666666667% !important}.medium-offset-6{margin-left:50% !important}.medium-offset-7{margin-left:58.3333333333% !important}.medium-offset-8{margin-left:66.6666666667% !important}.medium-offset-9{margin-left:75% !important}.medium-offset-10{margin-left:83.3333333333% !important}.medium-offset-11{margin-left:91.6666666667% !important}.medium-reset-order{margin-left:0;margin-right:0;left:auto;right:auto;float:left}.column.medium-centered,.columns.medium-centered{margin-left:auto;margin-right:auto;float:none}.column.medium-uncentered,.columns.medium-uncentered{margin-left:0;margin-right:0;float:left}.column.medium-centered:last-child,.columns.medium-centered:last-child{float:none}.column.medium-uncentered:last-child,.columns.medium-uncentered:last-child{float:left}.column.medium-uncentered.opposite,.columns.medium-uncentered.opposite{float:right}.row.medium-collapse>.column,.row.medium-collapse>.columns{padding-left:0;padding-right:0}.row.medium-collapse .row{margin-left:0;margin-right:0}.row.medium-uncollapse>.column,.row.medium-uncollapse>.columns{padding-left:.9375rem;padding-right:.9375rem;float:left}.push-0{position:relative;left:0%;right:auto}.pull-0{position:relative;right:0%;left:auto}.push-1{position:relative;left:8.3333333333%;right:auto}.pull-1{position:relative;right:8.3333333333%;left:auto}.push-2{position:relative;left:16.6666666667%;right:auto}.pull-2{position:relative;right:16.6666666667%;left:auto}.push-3{position:relative;left:25%;right:auto}.pull-3{position:relative;right:25%;left:auto}.push-4{position:relative;left:33.3333333333%;right:auto}.pull-4{position:relative;right:33.3333333333%;left:auto}.push-5{position:relative;left:41.6666666667%;right:auto}.pull-5{position:relative;right:41.6666666667%;left:auto}.push-6{position:relative;left:50%;right:auto}.pull-6{position:relative;right:50%;left:auto}.push-7{position:relative;left:58.3333333333%;right:auto}.pull-7{position:relative;right:58.3333333333%;left:auto}.push-8{position:relative;left:66.6666666667%;right:auto}.pull-8{position:relative;right:66.6666666667%;left:auto}.push-9{position:relative;left:75%;right:auto}.pull-9{position:relative;right:75%;left:auto}.push-10{position:relative;left:83.3333333333%;right:auto}.pull-10{position:relative;right:83.3333333333%;left:auto}.push-11{position:relative;left:91.6666666667%;right:auto}.pull-11{position:relative;right:91.6666666667%;left:auto}}@media only screen and (min-width: 64.0625em){.large-push-0{position:relative;left:0%;right:auto}.large-pull-0{position:relative;right:0%;left:auto}.large-push-1{position:relative;left:8.3333333333%;right:auto}.large-pull-1{position:relative;right:8.3333333333%;left:auto}.large-push-2{position:relative;left:16.6666666667%;right:auto}.large-pull-2{position:relative;right:16.6666666667%;left:auto}.large-push-3{position:relative;left:25%;right:auto}.large-pull-3{position:relative;right:25%;left:auto}.large-push-4{position:relative;left:33.3333333333%;right:auto}.large-pull-4{position:relative;right:33.3333333333%;left:auto}.large-push-5{position:relative;left:41.6666666667%;right:auto}.large-pull-5{position:relative;right:41.6666666667%;left:auto}.large-push-6{position:relative;left:50%;right:auto}.large-pull-6{position:relative;right:50%;left:auto}.large-push-7{position:relative;left:58.3333333333%;right:auto}.large-pull-7{position:relative;right:58.3333333333%;left:auto}.large-push-8{position:relative;left:66.6666666667%;right:auto}.large-pull-8{position:relative;right:66.6666666667%;left:auto}.large-push-9{position:relative;left:75%;right:auto}.large-pull-9{position:relative;right:75%;left:auto}.large-push-10{position:relative;left:83.3333333333%;right:auto}.large-pull-10{position:relative;right:83.3333333333%;left:auto}.large-push-11{position:relative;left:91.6666666667%;right:auto}.large-pull-11{position:relative;right:91.6666666667%;left:auto}.column,.columns{position:relative;padding-left:.9375rem;padding-right:.9375rem;float:left}.large-1{width:8.3333333333%}.large-2{width:16.6666666667%}.large-3{width:25%}.large-4{width:33.3333333333%}.large-5{width:41.6666666667%}.large-6{width:50%}.large-7{width:58.3333333333%}.large-8{width:66.6666666667%}.large-9{width:75%}.large-10{width:83.3333333333%}.large-11{width:91.6666666667%}.large-12{width:100%}.large-offset-0{margin-left:0% !important}.large-offset-1{margin-left:8.3333333333% !important}.large-offset-2{margin-left:16.6666666667% !important}.large-offset-3{margin-left:25% !important}.large-offset-4{margin-left:33.3333333333% !important}.large-offset-5{margin-left:41.6666666667% !important}.large-offset-6{margin-left:50% !important}.large-offset-7{margin-left:58.3333333333% !important}.large-offset-8{margin-left:66.6666666667% !important}.large-offset-9{margin-left:75% !important}.large-offset-10{margin-left:83.3333333333% !important}.large-offset-11{margin-left:91.6666666667% !important}.large-reset-order{margin-left:0;margin-right:0;left:auto;right:auto;float:left}.column.large-centered,.columns.large-centered{margin-left:auto;margin-right:auto;float:none}.column.large-uncentered,.columns.large-uncentered{margin-left:0;margin-right:0;float:left}.column.large-centered:last-child,.columns.large-centered:last-child{float:none}.column.large-uncentered:last-child,.columns.large-uncentered:last-child{float:left}.column.large-uncentered.opposite,.columns.large-uncentered.opposite{float:right}.row.large-collapse>.column,.row.large-collapse>.columns{padding-left:0;padding-right:0}.row.large-collapse .row{margin-left:0;margin-right:0}.row.large-uncollapse>.column,.row.large-uncollapse>.columns{padding-left:.9375rem;padding-right:.9375rem;float:left}.push-0{position:relative;left:0%;right:auto}.pull-0{position:relative;right:0%;left:auto}.push-1{position:relative;left:8.3333333333%;right:auto}.pull-1{position:relative;right:8.3333333333%;left:auto}.push-2{position:relative;left:16.6666666667%;right:auto}.pull-2{position:relative;right:16.6666666667%;left:auto}.push-3{position:relative;left:25%;right:auto}.pull-3{position:relative;right:25%;left:auto}.push-4{position:relative;left:33.3333333333%;right:auto}.pull-4{position:relative;right:33.3333333333%;left:auto}.push-5{position:relative;left:41.6666666667%;right:auto}.pull-5{position:relative;right:41.6666666667%;left:auto}.push-6{position:relative;left:50%;right:auto}.pull-6{position:relative;right:50%;left:auto}.push-7{position:relative;left:58.3333333333%;right:auto}.pull-7{position:relative;right:58.3333333333%;left:auto}.push-8{position:relative;left:66.6666666667%;right:auto}.pull-8{position:relative;right:66.6666666667%;left:auto}.push-9{position:relative;left:75%;right:auto}.pull-9{position:relative;right:75%;left:auto}.push-10{position:relative;left:83.3333333333%;right:auto}.pull-10{position:relative;right:83.3333333333%;left:auto}.push-11{position:relative;left:91.6666666667%;right:auto}.pull-11{position:relative;right:91.6666666667%;left:auto}}.inline-list{margin:0 auto 1.0625rem auto;margin-left:-1.375rem;margin-right:0;padding:0;list-style:none;overflow:hidden}.inline-list>li{list-style:none;float:left;margin-left:1.375rem;display:block}.inline-list>li>*{display:block}.panel{border-style:solid;border-width:1px;border-color:#d8d8d8;margin-bottom:1.25rem;padding:1.25rem;background:#f2f2f2;color:#333}.panel>:first-child{margin-top:0}.panel>:last-child{margin-bottom:0}.panel h1,.panel h2,.panel h3,.panel h4,.panel h5,.panel h6,.panel p,.panel li,.panel dl{color:#333}.panel h1,.panel h2,.panel h3,.panel h4,.panel h5,.panel h6{line-height:1;margin-bottom:.625rem}.panel h1.subheader,.panel h2.subheader,.panel h3.subheader,.panel h4.subheader,.panel h5.subheader,.panel h6.subheader{line-height:1.4}.panel.callout{border-style:solid;border-width:1px;border-color:#f6c4bf;margin-bottom:1.25rem;padding:1.25rem;background:#fdf0ef;color:#333}.panel.callout>:first-child{margin-top:0}.panel.callout>:last-child{margin-bottom:0}.panel.callout h1,.panel.callout h2,.panel.callout h3,.panel.callout h4,.panel.callout h5,.panel.callout h6,.panel.callout p,.panel.callout li,.panel.callout dl{color:#333}.panel.callout h1,.panel.callout h2,.panel.callout h3,.panel.callout h4,.panel.callout h5,.panel.callout h6{line-height:1;margin-bottom:.625rem}.panel.callout h1.subheader,.panel.callout h2.subheader,.panel.callout h3.subheader,.panel.callout h4.subheader,.panel.callout h5.subheader,.panel.callout h6.subheader{line-height:1.4}.panel.callout a:not(.button){color:#ba2619}.panel.callout a:not(.button):hover,.panel.callout a:not(.button):focus{color:#a02116}.panel.radius{border-radius:3px}.side-nav{display:block;margin:0;padding:.875rem 0;list-style-type:none;list-style-position:outside;font-family:"Open Sans","Helvetica Neue",Helvetica,Roboto,Arial,sans-serif}.side-nav li{margin:0 0 .4375rem 0;font-size:.875rem;font-weight:400}.side-nav li a:not(.button){display:block;color:#ba2619;margin:0;padding:.4375rem .875rem}.side-nav li a:not(.button):hover,.side-nav li a:not(.button):focus{background:rgba(0,0,0,0.025);color:#e65346}.side-nav li.active>a:first-child:not(.button){color:#e65346;font-weight:400;font-family:"Open Sans","Helvetica Neue",Helvetica,Roboto,Arial,sans-serif}.side-nav li.divider{border-top:1px solid;height:0;padding:0;list-style:none;border-top-color:#fff}.side-nav li.heading{color:#ba2619;font-size:.875rem;font-weight:bold;text-transform:uppercase}table{background:#fff;margin-bottom:1.25rem;border:solid 1px #ddd;table-layout:auto}table caption{background:transparent;color:#222;font-size:1rem;font-weight:bold}table thead{background:#f5f5f5}table thead tr th,table thead tr td{padding:.5rem .625rem .625rem;font-size:.875rem;font-weight:700;color:#222}table tfoot{background:#f5f5f5}table tfoot tr th,table tfoot tr td{padding:.5rem .625rem .625rem;font-size:.875rem;font-weight:700;color:#222}table tr th,table tr td{padding:.5625rem .625rem;font-size:.875rem;color:#222;text-align:left}table tr.even,table tr.alt,table tr:nth-of-type(even){background:#F9F9F9}table thead tr th,table tfoot tr th,table tfoot tr td,table tbody tr th,table tbody tr td,table tr td{display:table-cell;line-height:1.125rem}.th{line-height:0;display:inline-block;border:solid 4px #fff;max-width:100%;box-shadow:0 0 0 1px rgba(0,0,0,0.2);transition:all 200ms ease-out}.th:hover,.th:focus{box-shadow:0 0 6px 1px rgba(186,38,25,0.5)}.th.radius{border-radius:3px}meta.foundation-mq-topbar{font-family:"/only screen and (min-width:40.0625em)/";width:40.0625em}.contain-to-grid{width:100%;background:#333}.contain-to-grid .top-bar{margin-bottom:0}.fixed{width:100%;left:0;position:fixed;top:0;z-index:99}.fixed.expanded:not(.top-bar){overflow-y:auto;height:auto;width:100%;max-height:100%}.fixed.expanded:not(.top-bar) .title-area{position:fixed;width:100%;z-index:99}.fixed.expanded:not(.top-bar) .top-bar-section{z-index:98;margin-top:2.8125rem}.top-bar{overflow:hidden;height:2.8125rem;line-height:2.8125rem;position:relative;background:#333;margin-bottom:0}.top-bar ul{margin-bottom:0;list-style:none}.top-bar .row{max-width:none}.top-bar form,.top-bar input{margin-bottom:0}.top-bar input{height:1.75rem;padding-top:.35rem;padding-bottom:.35rem;font-size:.75rem}.top-bar .button,.top-bar button{padding-top:0.4125rem;padding-bottom:0.4125rem;margin-bottom:0;font-size:.75rem}@media only screen and (max-width: 40em){.top-bar .button,.top-bar button{position:relative;top:-1px}}.top-bar .title-area{position:relative;margin:0}.top-bar .name{height:2.8125rem;margin:0;font-size:16px}.top-bar .name h1,.top-bar .name h2,.top-bar .name h3,.top-bar .name h4,.top-bar .name p,.top-bar .name span{line-height:2.8125rem;font-size:1.0625rem;margin:0}.top-bar .name h1 a,.top-bar .name h2 a,.top-bar .name h3 a,.top-bar .name h4 a,.top-bar .name p a,.top-bar .name span a{font-weight:400;color:#fff;width:75%;display:block;padding:0 .9375rem}.top-bar .toggle-topbar{position:absolute;right:0;top:0}.top-bar .toggle-topbar a{color:#fff;text-transform:uppercase;font-size:.8125rem;font-weight:700;position:relative;display:block;padding:0 .9375rem;height:2.8125rem;line-height:2.8125rem}.top-bar .toggle-topbar.menu-icon{top:50%;margin-top:-16px}.top-bar .toggle-topbar.menu-icon a{height:34px;line-height:33px;padding:0 2.5rem 0 .9375rem;color:#fff;position:relative}.top-bar .toggle-topbar.menu-icon a span::after{content:"";position:absolute;display:block;height:0;top:50%;margin-top:-8px;right:.9375rem;box-shadow:0 0 0 1px #fff,0 7px 0 1px #fff,0 14px 0 1px #fff;width:16px}.top-bar .toggle-topbar.menu-icon a span:hover:after{box-shadow:0 0 0 1px "",0 7px 0 1px "",0 14px 0 1px ""}.top-bar.expanded{height:auto;background:transparent}.top-bar.expanded .title-area{background:#333}.top-bar.expanded .toggle-topbar a{color:#888}.top-bar.expanded .toggle-topbar a span::after{box-shadow:0 0 0 1px #888,0 7px 0 1px #888,0 14px 0 1px #888}.top-bar-section{left:0;position:relative;width:auto;transition:left 300ms ease-out}.top-bar-section ul{padding:0;width:100%;height:auto;display:block;font-size:16px;margin:0}.top-bar-section .divider,.top-bar-section [role="separator"]{border-top:solid 1px #1a1919;clear:both;height:1px;width:100%}.top-bar-section ul li{background:#333}.top-bar-section ul li>a{display:block;width:100%;color:#fff;padding:12px 0 12px 0;padding-left:.9375rem;font-family:"Open Sans","Helvetica Neue",Helvetica,Roboto,Arial,sans-serif;font-size:.8125rem;font-weight:400;text-transform:none}.top-bar-section ul li>a.button{font-size:.8125rem;padding-right:.9375rem;padding-left:.9375rem;background-color:#ba2619;border-color:#951e14;color:#fff}.top-bar-section ul li>a.button:hover,.top-bar-section ul li>a.button:focus{background-color:#951e14}.top-bar-section ul li>a.button:hover,.top-bar-section ul li>a.button:focus{color:#fff}.top-bar-section ul li>a.button.secondary{background-color:#e7e7e7;border-color:#b9b9b9;color:#333}.top-bar-section ul li>a.button.secondary:hover,.top-bar-section ul li>a.button.secondary:focus{background-color:#b9b9b9}.top-bar-section ul li>a.button.secondary:hover,.top-bar-section ul li>a.button.secondary:focus{color:#333}.top-bar-section ul li>a.button.success{background-color:#43AC6A;border-color:#368a55;color:#fff}.top-bar-section ul li>a.button.success:hover,.top-bar-section ul li>a.button.success:focus{background-color:#368a55}.top-bar-section ul li>a.button.success:hover,.top-bar-section ul li>a.button.success:focus{color:#fff}.top-bar-section ul li>a.button.alert{background-color:#f04124;border-color:#cf2a0e;color:#fff}.top-bar-section ul li>a.button.alert:hover,.top-bar-section ul li>a.button.alert:focus{background-color:#cf2a0e}.top-bar-section ul li>a.button.alert:hover,.top-bar-section ul li>a.button.alert:focus{color:#fff}.top-bar-section ul li>a.button.warning{background-color:#f08a24;border-color:#cf6e0e;color:#fff}.top-bar-section ul li>a.button.warning:hover,.top-bar-section ul li>a.button.warning:focus{background-color:#cf6e0e}.top-bar-section ul li>a.button.warning:hover,.top-bar-section ul li>a.button.warning:focus{color:#fff}.top-bar-section ul li>button{font-size:.8125rem;padding-right:.9375rem;padding-left:.9375rem;background-color:#ba2619;border-color:#951e14;color:#fff}.top-bar-section ul li>button:hover,.top-bar-section ul li>button:focus{background-color:#951e14}.top-bar-section ul li>button:hover,.top-bar-section ul li>button:focus{color:#fff}.top-bar-section ul li>button.secondary{background-color:#e7e7e7;border-color:#b9b9b9;color:#333}.top-bar-section ul li>button.secondary:hover,.top-bar-section ul li>button.secondary:focus{background-color:#b9b9b9}.top-bar-section ul li>button.secondary:hover,.top-bar-section ul li>button.secondary:focus{color:#333}.top-bar-section ul li>button.success{background-color:#43AC6A;border-color:#368a55;color:#fff}.top-bar-section ul li>button.success:hover,.top-bar-section ul li>button.success:focus{background-color:#368a55}.top-bar-section ul li>button.success:hover,.top-bar-section ul li>button.success:focus{color:#fff}.top-bar-section ul li>button.alert{background-color:#f04124;border-color:#cf2a0e;color:#fff}.top-bar-section ul li>button.alert:hover,.top-bar-section ul li>button.alert:focus{background-color:#cf2a0e}.top-bar-section ul li>button.alert:hover,.top-bar-section ul li>button.alert:focus{color:#fff}.top-bar-section ul li>button.warning{background-color:#f08a24;border-color:#cf6e0e;color:#fff}.top-bar-section ul li>button.warning:hover,.top-bar-section ul li>button.warning:focus{background-color:#cf6e0e}.top-bar-section ul li>button.warning:hover,.top-bar-section ul li>button.warning:focus{color:#fff}.top-bar-section ul li:hover:not(.has-form)>a{background-color:#555;background:#333;color:#fff}.top-bar-section ul li.active>a{background:#ba2619;color:#fff}.top-bar-section ul li.active>a:hover{background:#a02116;color:#fff}.top-bar-section .has-form{padding:.9375rem}.top-bar-section .has-dropdown{position:relative}.top-bar-section .has-dropdown>a:after{content:"";display:block;width:0;height:0;border:inset 5px;border-color:transparent transparent transparent rgba(255,255,255,0.4);border-left-style:solid;margin-right:.9375rem;margin-top:-4.5px;position:absolute;top:50%;right:0}.top-bar-section .has-dropdown.moved{position:static}.top-bar-section .has-dropdown.moved>.dropdown{display:block;position:static !important;height:auto;width:auto;overflow:visible;clip:auto;position:absolute !important;width:100%}.top-bar-section .has-dropdown.moved>a:after{display:none}.top-bar-section .dropdown{padding:0;position:absolute;left:100%;top:0;z-index:99;display:block;position:absolute !important;height:1px;width:1px;overflow:hidden;clip:rect(1px, 1px, 1px, 1px)}.top-bar-section .dropdown li{width:100%;height:auto}.top-bar-section .dropdown li a{font-weight:400;padding:8px .9375rem}.top-bar-section .dropdown li a.parent-link{font-weight:400}.top-bar-section .dropdown li.title h5,.top-bar-section .dropdown li.parent-link{margin-bottom:0;margin-top:0;font-size:1.125rem}.top-bar-section .dropdown li.title h5 a,.top-bar-section .dropdown li.parent-link a{color:#fff;display:block}.top-bar-section .dropdown li.title h5 a:hover,.top-bar-section .dropdown li.parent-link a:hover{background:none}.top-bar-section .dropdown li.has-form{padding:8px .9375rem}.top-bar-section .dropdown li .button,.top-bar-section .dropdown li button{top:auto}.top-bar-section .dropdown label{padding:8px .9375rem 2px;margin-bottom:0;text-transform:uppercase;color:#777;font-weight:700;font-size:.625rem}.js-generated{display:block}@media only screen and (min-width: 40.0625em){.top-bar{background:#333;overflow:visible}.top-bar:before,.top-bar:after{content:" ";display:table}.top-bar:after{clear:both}.top-bar .toggle-topbar{display:none}.top-bar .title-area{float:left}.top-bar .name h1 a,.top-bar .name h2 a,.top-bar .name h3 a,.top-bar .name h4 a,.top-bar .name h5 a,.top-bar .name h6 a{width:auto}.top-bar input,.top-bar .button,.top-bar button{font-size:.875rem;position:relative;height:1.75rem;top:.53125rem}.top-bar.expanded{background:#333}.contain-to-grid .top-bar{max-width:62.5rem;margin:0 auto;margin-bottom:0}.top-bar-section{transition:none 0 0;left:0 !important}.top-bar-section ul{width:auto;height:auto !important;display:inline}.top-bar-section ul li{float:left}.top-bar-section ul li .js-generated{display:none}.top-bar-section li.hover>a:not(.button){background-color:#555;background:#333;color:#fff}.top-bar-section li:not(.has-form) a:not(.button){padding:0 .9375rem;line-height:2.8125rem;background:#333}.top-bar-section li:not(.has-form) a:not(.button):hover{background-color:#555;background:#333}.top-bar-section li.active:not(.has-form) a:not(.button){padding:0 .9375rem;line-height:2.8125rem;color:#fff;background:#ba2619}.top-bar-section li.active:not(.has-form) a:not(.button):hover{background:#a02116;color:#fff}.top-bar-section .has-dropdown>a{padding-right:2.1875rem !important}.top-bar-section .has-dropdown>a:after{content:"";display:block;width:0;height:0;border:inset 5px;border-color:rgba(255,255,255,0.4) transparent transparent transparent;border-top-style:solid;margin-top:-2.5px;top:1.40625rem}.top-bar-section .has-dropdown.moved{position:relative}.top-bar-section .has-dropdown.moved>.dropdown{display:block;position:absolute !important;height:1px;width:1px;overflow:hidden;clip:rect(1px, 1px, 1px, 1px)}.top-bar-section .has-dropdown.hover>.dropdown,.top-bar-section .has-dropdown.not-click:hover>.dropdown{display:block;position:static !important;height:auto;width:auto;overflow:visible;clip:auto;position:absolute !important}.top-bar-section .has-dropdown>a:focus+.dropdown{display:block;position:static !important;height:auto;width:auto;overflow:visible;clip:auto;position:absolute !important}.top-bar-section .has-dropdown .dropdown li.has-dropdown>a:after{border:none;content:"\00bb";top:1rem;margin-top:-1px;right:5px;line-height:1.2}.top-bar-section .dropdown{left:0;top:auto;background:transparent;min-width:100%}.top-bar-section .dropdown li a{color:#fff;line-height:2.8125rem;white-space:nowrap;padding:12px .9375rem;background:#333}.top-bar-section .dropdown li:not(.has-form):not(.active)>a:not(.button){color:#fff;background:#333}.top-bar-section .dropdown li:not(.has-form):not(.active):hover>a:not(.button){color:#fff;background-color:#555;background:#333}.top-bar-section .dropdown li label{white-space:nowrap;background:#333}.top-bar-section .dropdown li .dropdown{left:100%;top:0}.top-bar-section>ul>.divider,.top-bar-section>ul>[role="separator"]{border-bottom:none;border-top:none;border-right:solid 1px #4e4e4e;clear:none;height:2.8125rem;width:0}.top-bar-section .has-form{background:#333;padding:0 .9375rem;height:2.8125rem}.top-bar-section .right li .dropdown{left:auto;right:0}.top-bar-section .right li .dropdown li .dropdown{right:100%}.top-bar-section .left li .dropdown{right:auto;left:0}.top-bar-section .left li .dropdown li .dropdown{left:100%}.no-js .top-bar-section ul li:hover>a{background-color:#555;background:#333;color:#fff}.no-js .top-bar-section ul li:active>a{background:#ba2619;color:#fff}.no-js .top-bar-section .has-dropdown:hover>.dropdown{display:block;position:static !important;height:auto;width:auto;overflow:visible;clip:auto;position:absolute !important}.no-js .top-bar-section .has-dropdown>a:focus+.dropdown{display:block;position:static !important;height:auto;width:auto;overflow:visible;clip:auto;position:absolute !important}}.text-left{text-align:left !important}.text-right{text-align:right !important}.text-center{text-align:center !important}.text-justify{text-align:justify !important}@media only screen and (max-width: 40em){.small-only-text-left{text-align:left !important}.small-only-text-right{text-align:right !important}.small-only-text-center{text-align:center !important}.small-only-text-justify{text-align:justify !important}}@media only screen{.small-text-left{text-align:left !important}.small-text-right{text-align:right !important}.small-text-center{text-align:center !important}.small-text-justify{text-align:justify !important}}@media only screen and (min-width: 40.0625em) and (max-width: 64em){.medium-only-text-left{text-align:left !important}.medium-only-text-right{text-align:right !important}.medium-only-text-center{text-align:center !important}.medium-only-text-justify{text-align:justify !important}}@media only screen and (min-width: 40.0625em){.medium-text-left{text-align:left !important}.medium-text-right{text-align:right !important}.medium-text-center{text-align:center !important}.medium-text-justify{text-align:justify !important}}@media only screen and (min-width: 64.0625em) and (max-width: 90em){.large-only-text-left{text-align:left !important}.large-only-text-right{text-align:right !important}.large-only-text-center{text-align:center !important}.large-only-text-justify{text-align:justify !important}}@media only screen and (min-width: 64.0625em){.large-text-left{text-align:left !important}.large-text-right{text-align:right !important}.large-text-center{text-align:center !important}.large-text-justify{text-align:justify !important}}@media only screen and (min-width: 90.0625em) and (max-width: 120em){.xlarge-only-text-left{text-align:left !important}.xlarge-only-text-right{text-align:right !important}.xlarge-only-text-center{text-align:center !important}.xlarge-only-text-justify{text-align:justify !important}}@media only screen and (min-width: 90.0625em){.xlarge-text-left{text-align:left !important}.xlarge-text-right{text-align:right !important}.xlarge-text-center{text-align:center !important}.xlarge-text-justify{text-align:justify !important}}@media only screen and (min-width: 120.0625em) and (max-width: 99999999em){.xxlarge-only-text-left{text-align:left !important}.xxlarge-only-text-right{text-align:right !important}.xxlarge-only-text-center{text-align:center !important}.xxlarge-only-text-justify{text-align:justify !important}}@media only screen and (min-width: 120.0625em){.xxlarge-text-left{text-align:left !important}.xxlarge-text-right{text-align:right !important}.xxlarge-text-center{text-align:center !important}.xxlarge-text-justify{text-align:justify !important}}div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0}a{color:#ba2619;text-decoration:none;line-height:inherit}a:hover,a:focus{color:#a02116}a img{border:none}p{font-family:inherit;font-weight:400;font-size:1rem;line-height:1.6;margin-bottom:1.25rem;text-rendering:optimizeLegibility}p.lead{font-size:1.21875rem;line-height:1.6}p aside{font-size:.875rem;line-height:1.35;font-style:italic}h1,h2,h3,h4,h5,h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Roboto,Arial,sans-serif;font-weight:700;font-style:normal;color:#222;text-rendering:optimizeLegibility;margin-top:.2rem;margin-bottom:.5rem;line-height:1.4}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-size:80%;color:#6f6f6f;line-height:0}h1{font-size:1.5625rem}h2{font-size:1.25rem}h3{font-size:1.0625rem}h4{font-size:.9375rem}h5{font-size:1rem}h6{font-size:1rem}.subheader{line-height:1.4;color:#6f6f6f;font-weight:400;margin-top:.2rem;margin-bottom:.5rem}hr{border:solid #ddd;border-width:1px 0 0;clear:both;margin:1.25rem 0 1.1875rem;height:0}em,i{font-style:italic;line-height:inherit}strong,b{font-weight:700;line-height:inherit}small{font-size:80%;line-height:inherit}code{font-family:Consolas,"Liberation Mono",Courier,monospace;font-weight:400;color:#333;background-color:rgba(0,0,0,0.04);border-width:1px;border-style:none;border-color:rgba(0,0,0,0.04);padding:.125rem .3125rem .0625rem}ul,ol,dl{font-size:1rem;line-height:1.6;margin-bottom:1.25rem;list-style-position:outside;font-family:inherit}ul{margin-left:1.1rem}ul.no-bullet{margin-left:0}ul.no-bullet li ul,ul.no-bullet li ol{margin-left:1.25rem;margin-bottom:0;list-style:none}ul li ul,ul li ol{margin-left:1.25rem;margin-bottom:0}ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}ul.square{list-style-type:square;margin-left:1.1rem}ul.circle{list-style-type:circle;margin-left:1.1rem}ul.disc{list-style-type:disc;margin-left:1.1rem}ul.no-bullet{list-style:none}ol{margin-left:1.4rem}ol li ul,ol li ol{margin-left:1.25rem;margin-bottom:0}dl dt{margin-bottom:.3rem;font-weight:700}dl dd{margin-bottom:.75rem}abbr,acronym{text-transform:uppercase;font-size:90%;color:#222;cursor:help}abbr{text-transform:none}abbr[title]{border-bottom:1px dotted #ddd}blockquote{margin:0 0 1.25rem;padding:.5625rem 1.25rem 0 1.1875rem;border-left:1px solid #ddd}blockquote cite{display:block;font-size:.8125rem;color:#555}blockquote cite:before{content:"\2014 \0020"}blockquote cite a,blockquote cite a:visited{color:#555}blockquote,blockquote p{line-height:1.6;color:#6f6f6f}.vcard{display:inline-block;margin:0 0 1.25rem 0;border:1px solid #ddd;padding:.625rem .75rem}.vcard li{margin:0;display:block}.vcard .fn{font-weight:700;font-size:.9375rem}.vevent .summary{font-weight:700}.vevent abbr{cursor:default;text-decoration:none;font-weight:700;border:none;padding:0 .0625rem}@media only screen and (min-width: 40.0625em){h1,h2,h3,h4,h5,h6{line-height:1.4}h1{font-size:1.875rem}h2{font-size:1.5625rem}h3{font-size:1.375rem}h4{font-size:1.25rem}h5{font-size:1rem}h6{font-size:1rem}}@media only screen{.show-for-small-only,.show-for-small-up,.show-for-small,.show-for-small-down,.hide-for-medium-only,.hide-for-medium-up,.hide-for-medium,.show-for-medium-down,.hide-for-large-only,.hide-for-large-up,.hide-for-large,.show-for-large-down,.hide-for-xlarge-only,.hide-for-xlarge-up,.hide-for-xlarge,.show-for-xlarge-down,.hide-for-xxlarge-only,.hide-for-xxlarge-up,.hide-for-xxlarge,.show-for-xxlarge-down{display:inherit !important}.hide-for-small-only,.hide-for-small-up,.hide-for-small,.hide-for-small-down,.show-for-medium-only,.show-for-medium-up,.show-for-medium,.hide-for-medium-down,.show-for-large-only,.show-for-large-up,.show-for-large,.hide-for-large-down,.show-for-xlarge-only,.show-for-xlarge-up,.show-for-xlarge,.hide-for-xlarge-down,.show-for-xxlarge-only,.show-for-xxlarge-up,.show-for-xxlarge,.hide-for-xxlarge-down{display:none !important}.visible-for-small-only,.visible-for-small-up,.visible-for-small,.visible-for-small-down,.hidden-for-medium-only,.hidden-for-medium-up,.hidden-for-medium,.visible-for-medium-down,.hidden-for-large-only,.hidden-for-large-up,.hidden-for-large,.visible-for-large-down,.hidden-for-xlarge-only,.hidden-for-xlarge-up,.hidden-for-xlarge,.visible-for-xlarge-down,.hidden-for-xxlarge-only,.hidden-for-xxlarge-up,.hidden-for-xxlarge,.visible-for-xxlarge-down{position:static !important;height:auto;width:auto;overflow:visible;clip:auto}.hidden-for-small-only,.hidden-for-small-up,.hidden-for-small,.hidden-for-small-down,.visible-for-medium-only,.visible-for-medium-up,.visible-for-medium,.hidden-for-medium-down,.visible-for-large-only,.visible-for-large-up,.visible-for-large,.hidden-for-large-down,.visible-for-xlarge-only,.visible-for-xlarge-up,.visible-for-xlarge,.hidden-for-xlarge-down,.visible-for-xxlarge-only,.visible-for-xxlarge-up,.visible-for-xxlarge,.hidden-for-xxlarge-down{position:absolute !important;height:1px;width:1px;overflow:hidden;clip:rect(1px, 1px, 1px, 1px)}table.show-for-small-only,table.show-for-small-up,table.show-for-small,table.show-for-small-down,table.hide-for-medium-only,table.hide-for-medium-up,table.hide-for-medium,table.show-for-medium-down,table.hide-for-large-only,table.hide-for-large-up,table.hide-for-large,table.show-for-large-down,table.hide-for-xlarge-only,table.hide-for-xlarge-up,table.hide-for-xlarge,table.show-for-xlarge-down,table.hide-for-xxlarge-only,table.hide-for-xxlarge-up,table.hide-for-xxlarge,table.show-for-xxlarge-down{display:table !important}thead.show-for-small-only,thead.show-for-small-up,thead.show-for-small,thead.show-for-small-down,thead.hide-for-medium-only,thead.hide-for-medium-up,thead.hide-for-medium,thead.show-for-medium-down,thead.hide-for-large-only,thead.hide-for-large-up,thead.hide-for-large,thead.show-for-large-down,thead.hide-for-xlarge-only,thead.hide-for-xlarge-up,thead.hide-for-xlarge,thead.show-for-xlarge-down,thead.hide-for-xxlarge-only,thead.hide-for-xxlarge-up,thead.hide-for-xxlarge,thead.show-for-xxlarge-down{display:table-header-group !important}tbody.show-for-small-only,tbody.show-for-small-up,tbody.show-for-small,tbody.show-for-small-down,tbody.hide-for-medium-only,tbody.hide-for-medium-up,tbody.hide-for-medium,tbody.show-for-medium-down,tbody.hide-for-large-only,tbody.hide-for-large-up,tbody.hide-for-large,tbody.show-for-large-down,tbody.hide-for-xlarge-only,tbody.hide-for-xlarge-up,tbody.hide-for-xlarge,tbody.show-for-xlarge-down,tbody.hide-for-xxlarge-only,tbody.hide-for-xxlarge-up,tbody.hide-for-xxlarge,tbody.show-for-xxlarge-down{display:table-row-group !important}tr.show-for-small-only,tr.show-for-small-up,tr.show-for-small,tr.show-for-small-down,tr.hide-for-medium-only,tr.hide-for-medium-up,tr.hide-for-medium,tr.show-for-medium-down,tr.hide-for-large-only,tr.hide-for-large-up,tr.hide-for-large,tr.show-for-large-down,tr.hide-for-xlarge-only,tr.hide-for-xlarge-up,tr.hide-for-xlarge,tr.show-for-xlarge-down,tr.hide-for-xxlarge-only,tr.hide-for-xxlarge-up,tr.hide-for-xxlarge,tr.show-for-xxlarge-down{display:table-row}th.show-for-small-only,td.show-for-small-only,th.show-for-small-up,td.show-for-small-up,th.show-for-small,td.show-for-small,th.show-for-small-down,td.show-for-small-down,th.hide-for-medium-only,td.hide-for-medium-only,th.hide-for-medium-up,td.hide-for-medium-up,th.hide-for-medium,td.hide-for-medium,th.show-for-medium-down,td.show-for-medium-down,th.hide-for-large-only,td.hide-for-large-only,th.hide-for-large-up,td.hide-for-large-up,th.hide-for-large,td.hide-for-large,th.show-for-large-down,td.show-for-large-down,th.hide-for-xlarge-only,td.hide-for-xlarge-only,th.hide-for-xlarge-up,td.hide-for-xlarge-up,th.hide-for-xlarge,td.hide-for-xlarge,th.show-for-xlarge-down,td.show-for-xlarge-down,th.hide-for-xxlarge-only,td.hide-for-xxlarge-only,th.hide-for-xxlarge-up,td.hide-for-xxlarge-up,th.hide-for-xxlarge,td.hide-for-xxlarge,th.show-for-xxlarge-down,td.show-for-xxlarge-down{display:table-cell !important}}@media only screen and (min-width: 40.0625em){.hide-for-small-only,.show-for-small-up,.hide-for-small,.hide-for-small-down,.show-for-medium-only,.show-for-medium-up,.show-for-medium,.show-for-medium-down,.hide-for-large-only,.hide-for-large-up,.hide-for-large,.show-for-large-down,.hide-for-xlarge-only,.hide-for-xlarge-up,.hide-for-xlarge,.show-for-xlarge-down,.hide-for-xxlarge-only,.hide-for-xxlarge-up,.hide-for-xxlarge,.show-for-xxlarge-down{display:inherit !important}.show-for-small-only,.hide-for-small-up,.show-for-small,.show-for-small-down,.hide-for-medium-only,.hide-for-medium-up,.hide-for-medium,.hide-for-medium-down,.show-for-large-only,.show-for-large-up,.show-for-large,.hide-for-large-down,.show-for-xlarge-only,.show-for-xlarge-up,.show-for-xlarge,.hide-for-xlarge-down,.show-for-xxlarge-only,.show-for-xxlarge-up,.show-for-xxlarge,.hide-for-xxlarge-down{display:none !important}.hidden-for-small-only,.visible-for-small-up,.hidden-for-small,.hidden-for-small-down,.visible-for-medium-only,.visible-for-medium-up,.visible-for-medium,.visible-for-medium-down,.hidden-for-large-only,.hidden-for-large-up,.hidden-for-large,.visible-for-large-down,.hidden-for-xlarge-only,.hidden-for-xlarge-up,.hidden-for-xlarge,.visible-for-xlarge-down,.hidden-for-xxlarge-only,.hidden-for-xxlarge-up,.hidden-for-xxlarge,.visible-for-xxlarge-down{position:static !important;height:auto;width:auto;overflow:visible;clip:auto}.visible-for-small-only,.hidden-for-small-up,.visible-for-small,.visible-for-small-down,.hidden-for-medium-only,.hidden-for-medium-up,.hidden-for-medium,.hidden-for-medium-down,.visible-for-large-only,.visible-for-large-up,.visible-for-large,.hidden-for-large-down,.visible-for-xlarge-only,.visible-for-xlarge-up,.visible-for-xlarge,.hidden-for-xlarge-down,.visible-for-xxlarge-only,.visible-for-xxlarge-up,.visible-for-xxlarge,.hidden-for-xxlarge-down{position:absolute !important;height:1px;width:1px;overflow:hidden;clip:rect(1px, 1px, 1px, 1px)}table.hide-for-small-only,table.show-for-small-up,table.hide-for-small,table.hide-for-small-down,table.show-for-medium-only,table.show-for-medium-up,table.show-for-medium,table.show-for-medium-down,table.hide-for-large-only,table.hide-for-large-up,table.hide-for-large,table.show-for-large-down,table.hide-for-xlarge-only,table.hide-for-xlarge-up,table.hide-for-xlarge,table.show-for-xlarge-down,table.hide-for-xxlarge-only,table.hide-for-xxlarge-up,table.hide-for-xxlarge,table.show-for-xxlarge-down{display:table !important}thead.hide-for-small-only,thead.show-for-small-up,thead.hide-for-small,thead.hide-for-small-down,thead.show-for-medium-only,thead.show-for-medium-up,thead.show-for-medium,thead.show-for-medium-down,thead.hide-for-large-only,thead.hide-for-large-up,thead.hide-for-large,thead.show-for-large-down,thead.hide-for-xlarge-only,thead.hide-for-xlarge-up,thead.hide-for-xlarge,thead.show-for-xlarge-down,thead.hide-for-xxlarge-only,thead.hide-for-xxlarge-up,thead.hide-for-xxlarge,thead.show-for-xxlarge-down{display:table-header-group !important}tbody.hide-for-small-only,tbody.show-for-small-up,tbody.hide-for-small,tbody.hide-for-small-down,tbody.show-for-medium-only,tbody.show-for-medium-up,tbody.show-for-medium,tbody.show-for-medium-down,tbody.hide-for-large-only,tbody.hide-for-large-up,tbody.hide-for-large,tbody.show-for-large-down,tbody.hide-for-xlarge-only,tbody.hide-for-xlarge-up,tbody.hide-for-xlarge,tbody.show-for-xlarge-down,tbody.hide-for-xxlarge-only,tbody.hide-for-xxlarge-up,tbody.hide-for-xxlarge,tbody.show-for-xxlarge-down{display:table-row-group !important}tr.hide-for-small-only,tr.show-for-small-up,tr.hide-for-small,tr.hide-for-small-down,tr.show-for-medium-only,tr.show-for-medium-up,tr.show-for-medium,tr.show-for-medium-down,tr.hide-for-large-only,tr.hide-for-large-up,tr.hide-for-large,tr.show-for-large-down,tr.hide-for-xlarge-only,tr.hide-for-xlarge-up,tr.hide-for-xlarge,tr.show-for-xlarge-down,tr.hide-for-xxlarge-only,tr.hide-for-xxlarge-up,tr.hide-for-xxlarge,tr.show-for-xxlarge-down{display:table-row}th.hide-for-small-only,td.hide-for-small-only,th.show-for-small-up,td.show-for-small-up,th.hide-for-small,td.hide-for-small,th.hide-for-small-down,td.hide-for-small-down,th.show-for-medium-only,td.show-for-medium-only,th.show-for-medium-up,td.show-for-medium-up,th.show-for-medium,td.show-for-medium,th.show-for-medium-down,td.show-for-medium-down,th.hide-for-large-only,td.hide-for-large-only,th.hide-for-large-up,td.hide-for-large-up,th.hide-for-large,td.hide-for-large,th.show-for-large-down,td.show-for-large-down,th.hide-for-xlarge-only,td.hide-for-xlarge-only,th.hide-for-xlarge-up,td.hide-for-xlarge-up,th.hide-for-xlarge,td.hide-for-xlarge,th.show-for-xlarge-down,td.show-for-xlarge-down,th.hide-for-xxlarge-only,td.hide-for-xxlarge-only,th.hide-for-xxlarge-up,td.hide-for-xxlarge-up,th.hide-for-xxlarge,td.hide-for-xxlarge,th.show-for-xxlarge-down,td.show-for-xxlarge-down{display:table-cell !important}}@media only screen and (min-width: 64.0625em){.hide-for-small-only,.show-for-small-up,.hide-for-small,.hide-for-small-down,.hide-for-medium-only,.show-for-medium-up,.hide-for-medium,.hide-for-medium-down,.show-for-large-only,.show-for-large-up,.show-for-large,.show-for-large-down,.hide-for-xlarge-only,.hide-for-xlarge-up,.hide-for-xlarge,.show-for-xlarge-down,.hide-for-xxlarge-only,.hide-for-xxlarge-up,.hide-for-xxlarge,.show-for-xxlarge-down{display:inherit !important}.show-for-small-only,.hide-for-small-up,.show-for-small,.show-for-small-down,.show-for-medium-only,.hide-for-medium-up,.show-for-medium,.show-for-medium-down,.hide-for-large-only,.hide-for-large-up,.hide-for-large,.hide-for-large-down,.show-for-xlarge-only,.show-for-xlarge-up,.show-for-xlarge,.hide-for-xlarge-down,.show-for-xxlarge-only,.show-for-xxlarge-up,.show-for-xxlarge,.hide-for-xxlarge-down{display:none !important}.hidden-for-small-only,.visible-for-small-up,.hidden-for-small,.hidden-for-small-down,.hidden-for-medium-only,.visible-for-medium-up,.hidden-for-medium,.hidden-for-medium-down,.visible-for-large-only,.visible-for-large-up,.visible-for-large,.visible-for-large-down,.hidden-for-xlarge-only,.hidden-for-xlarge-up,.hidden-for-xlarge,.visible-for-xlarge-down,.hidden-for-xxlarge-only,.hidden-for-xxlarge-up,.hidden-for-xxlarge,.visible-for-xxlarge-down{position:static !important;height:auto;width:auto;overflow:visible;clip:auto}.visible-for-small-only,.hidden-for-small-up,.visible-for-small,.visible-for-small-down,.visible-for-medium-only,.hidden-for-medium-up,.visible-for-medium,.visible-for-medium-down,.hidden-for-large-only,.hidden-for-large-up,.hidden-for-large,.hidden-for-large-down,.visible-for-xlarge-only,.visible-for-xlarge-up,.visible-for-xlarge,.hidden-for-xlarge-down,.visible-for-xxlarge-only,.visible-for-xxlarge-up,.visible-for-xxlarge,.hidden-for-xxlarge-down{position:absolute !important;height:1px;width:1px;overflow:hidden;clip:rect(1px, 1px, 1px, 1px)}table.hide-for-small-only,table.show-for-small-up,table.hide-for-small,table.hide-for-small-down,table.hide-for-medium-only,table.show-for-medium-up,table.hide-for-medium,table.hide-for-medium-down,table.show-for-large-only,table.show-for-large-up,table.show-for-large,table.show-for-large-down,table.hide-for-xlarge-only,table.hide-for-xlarge-up,table.hide-for-xlarge,table.show-for-xlarge-down,table.hide-for-xxlarge-only,table.hide-for-xxlarge-up,table.hide-for-xxlarge,table.show-for-xxlarge-down{display:table !important}thead.hide-for-small-only,thead.show-for-small-up,thead.hide-for-small,thead.hide-for-small-down,thead.hide-for-medium-only,thead.show-for-medium-up,thead.hide-for-medium,thead.hide-for-medium-down,thead.show-for-large-only,thead.show-for-large-up,thead.show-for-large,thead.show-for-large-down,thead.hide-for-xlarge-only,thead.hide-for-xlarge-up,thead.hide-for-xlarge,thead.show-for-xlarge-down,thead.hide-for-xxlarge-only,thead.hide-for-xxlarge-up,thead.hide-for-xxlarge,thead.show-for-xxlarge-down{display:table-header-group !important}tbody.hide-for-small-only,tbody.show-for-small-up,tbody.hide-for-small,tbody.hide-for-small-down,tbody.hide-for-medium-only,tbody.show-for-medium-up,tbody.hide-for-medium,tbody.hide-for-medium-down,tbody.show-for-large-only,tbody.show-for-large-up,tbody.show-for-large,tbody.show-for-large-down,tbody.hide-for-xlarge-only,tbody.hide-for-xlarge-up,tbody.hide-for-xlarge,tbody.show-for-xlarge-down,tbody.hide-for-xxlarge-only,tbody.hide-for-xxlarge-up,tbody.hide-for-xxlarge,tbody.show-for-xxlarge-down{display:table-row-group !important}tr.hide-for-small-only,tr.show-for-small-up,tr.hide-for-small,tr.hide-for-small-down,tr.hide-for-medium-only,tr.show-for-medium-up,tr.hide-for-medium,tr.hide-for-medium-down,tr.show-for-large-only,tr.show-for-large-up,tr.show-for-large,tr.show-for-large-down,tr.hide-for-xlarge-only,tr.hide-for-xlarge-up,tr.hide-for-xlarge,tr.show-for-xlarge-down,tr.hide-for-xxlarge-only,tr.hide-for-xxlarge-up,tr.hide-for-xxlarge,tr.show-for-xxlarge-down{display:table-row}th.hide-for-small-only,td.hide-for-small-only,th.show-for-small-up,td.show-for-small-up,th.hide-for-small,td.hide-for-small,th.hide-for-small-down,td.hide-for-small-down,th.hide-for-medium-only,td.hide-for-medium-only,th.show-for-medium-up,td.show-for-medium-up,th.hide-for-medium,td.hide-for-medium,th.hide-for-medium-down,td.hide-for-medium-down,th.show-for-large-only,td.show-for-large-only,th.show-for-large-up,td.show-for-large-up,th.show-for-large,td.show-for-large,th.show-for-large-down,td.show-for-large-down,th.hide-for-xlarge-only,td.hide-for-xlarge-only,th.hide-for-xlarge-up,td.hide-for-xlarge-up,th.hide-for-xlarge,td.hide-for-xlarge,th.show-for-xlarge-down,td.show-for-xlarge-down,th.hide-for-xxlarge-only,td.hide-for-xxlarge-only,th.hide-for-xxlarge-up,td.hide-for-xxlarge-up,th.hide-for-xxlarge,td.hide-for-xxlarge,th.show-for-xxlarge-down,td.show-for-xxlarge-down{display:table-cell !important}}@media only screen and (min-width: 90.0625em){.hide-for-small-only,.show-for-small-up,.hide-for-small,.hide-for-small-down,.hide-for-medium-only,.show-for-medium-up,.hide-for-medium,.hide-for-medium-down,.hide-for-large-only,.show-for-large-up,.hide-for-large,.hide-for-large-down,.show-for-xlarge-only,.show-for-xlarge-up,.show-for-xlarge,.show-for-xlarge-down,.hide-for-xxlarge-only,.hide-for-xxlarge-up,.hide-for-xxlarge,.show-for-xxlarge-down{display:inherit !important}.show-for-small-only,.hide-for-small-up,.show-for-small,.show-for-small-down,.show-for-medium-only,.hide-for-medium-up,.show-for-medium,.show-for-medium-down,.show-for-large-only,.hide-for-large-up,.show-for-large,.show-for-large-down,.hide-for-xlarge-only,.hide-for-xlarge-up,.hide-for-xlarge,.hide-for-xlarge-down,.show-for-xxlarge-only,.show-for-xxlarge-up,.show-for-xxlarge,.hide-for-xxlarge-down{display:none !important}.hidden-for-small-only,.visible-for-small-up,.hidden-for-small,.hidden-for-small-down,.hidden-for-medium-only,.visible-for-medium-up,.hidden-for-medium,.hidden-for-medium-down,.hidden-for-large-only,.visible-for-large-up,.hidden-for-large,.hidden-for-large-down,.visible-for-xlarge-only,.visible-for-xlarge-up,.visible-for-xlarge,.visible-for-xlarge-down,.hidden-for-xxlarge-only,.hidden-for-xxlarge-up,.hidden-for-xxlarge,.visible-for-xxlarge-down{position:static !important;height:auto;width:auto;overflow:visible;clip:auto}.visible-for-small-only,.hidden-for-small-up,.visible-for-small,.visible-for-small-down,.visible-for-medium-only,.hidden-for-medium-up,.visible-for-medium,.visible-for-medium-down,.visible-for-large-only,.hidden-for-large-up,.visible-for-large,.visible-for-large-down,.hidden-for-xlarge-only,.hidden-for-xlarge-up,.hidden-for-xlarge,.hidden-for-xlarge-down,.visible-for-xxlarge-only,.visible-for-xxlarge-up,.visible-for-xxlarge,.hidden-for-xxlarge-down{position:absolute !important;height:1px;width:1px;overflow:hidden;clip:rect(1px, 1px, 1px, 1px)}table.hide-for-small-only,table.show-for-small-up,table.hide-for-small,table.hide-for-small-down,table.hide-for-medium-only,table.show-for-medium-up,table.hide-for-medium,table.hide-for-medium-down,table.hide-for-large-only,table.show-for-large-up,table.hide-for-large,table.hide-for-large-down,table.show-for-xlarge-only,table.show-for-xlarge-up,table.show-for-xlarge,table.show-for-xlarge-down,table.hide-for-xxlarge-only,table.hide-for-xxlarge-up,table.hide-for-xxlarge,table.show-for-xxlarge-down{display:table !important}thead.hide-for-small-only,thead.show-for-small-up,thead.hide-for-small,thead.hide-for-small-down,thead.hide-for-medium-only,thead.show-for-medium-up,thead.hide-for-medium,thead.hide-for-medium-down,thead.hide-for-large-only,thead.show-for-large-up,thead.hide-for-large,thead.hide-for-large-down,thead.show-for-xlarge-only,thead.show-for-xlarge-up,thead.show-for-xlarge,thead.show-for-xlarge-down,thead.hide-for-xxlarge-only,thead.hide-for-xxlarge-up,thead.hide-for-xxlarge,thead.show-for-xxlarge-down{display:table-header-group !important}tbody.hide-for-small-only,tbody.show-for-small-up,tbody.hide-for-small,tbody.hide-for-small-down,tbody.hide-for-medium-only,tbody.show-for-medium-up,tbody.hide-for-medium,tbody.hide-for-medium-down,tbody.hide-for-large-only,tbody.show-for-large-up,tbody.hide-for-large,tbody.hide-for-large-down,tbody.show-for-xlarge-only,tbody.show-for-xlarge-up,tbody.show-for-xlarge,tbody.show-for-xlarge-down,tbody.hide-for-xxlarge-only,tbody.hide-for-xxlarge-up,tbody.hide-for-xxlarge,tbody.show-for-xxlarge-down{display:table-row-group !important}tr.hide-for-small-only,tr.show-for-small-up,tr.hide-for-small,tr.hide-for-small-down,tr.hide-for-medium-only,tr.show-for-medium-up,tr.hide-for-medium,tr.hide-for-medium-down,tr.hide-for-large-only,tr.show-for-large-up,tr.hide-for-large,tr.hide-for-large-down,tr.show-for-xlarge-only,tr.show-for-xlarge-up,tr.show-for-xlarge,tr.show-for-xlarge-down,tr.hide-for-xxlarge-only,tr.hide-for-xxlarge-up,tr.hide-for-xxlarge,tr.show-for-xxlarge-down{display:table-row}th.hide-for-small-only,td.hide-for-small-only,th.show-for-small-up,td.show-for-small-up,th.hide-for-small,td.hide-for-small,th.hide-for-small-down,td.hide-for-small-down,th.hide-for-medium-only,td.hide-for-medium-only,th.show-for-medium-up,td.show-for-medium-up,th.hide-for-medium,td.hide-for-medium,th.hide-for-medium-down,td.hide-for-medium-down,th.hide-for-large-only,td.hide-for-large-only,th.show-for-large-up,td.show-for-large-up,th.hide-for-large,td.hide-for-large,th.hide-for-large-down,td.hide-for-large-down,th.show-for-xlarge-only,td.show-for-xlarge-only,th.show-for-xlarge-up,td.show-for-xlarge-up,th.show-for-xlarge,td.show-for-xlarge,th.show-for-xlarge-down,td.show-for-xlarge-down,th.hide-for-xxlarge-only,td.hide-for-xxlarge-only,th.hide-for-xxlarge-up,td.hide-for-xxlarge-up,th.hide-for-xxlarge,td.hide-for-xxlarge,th.show-for-xxlarge-down,td.show-for-xxlarge-down{display:table-cell !important}}@media only screen and (min-width: 120.0625em){.hide-for-small-only,.show-for-small-up,.hide-for-small,.hide-for-small-down,.hide-for-medium-only,.show-for-medium-up,.hide-for-medium,.hide-for-medium-down,.hide-for-large-only,.show-for-large-up,.hide-for-large,.hide-for-large-down,.hide-for-xlarge-only,.show-for-xlarge-up,.hide-for-xlarge,.hide-for-xlarge-down,.show-for-xxlarge-only,.show-for-xxlarge-up,.show-for-xxlarge,.show-for-xxlarge-down{display:inherit !important}.show-for-small-only,.hide-for-small-up,.show-for-small,.show-for-small-down,.show-for-medium-only,.hide-for-medium-up,.show-for-medium,.show-for-medium-down,.show-for-large-only,.hide-for-large-up,.show-for-large,.show-for-large-down,.show-for-xlarge-only,.hide-for-xlarge-up,.show-for-xlarge,.show-for-xlarge-down,.hide-for-xxlarge-only,.hide-for-xxlarge-up,.hide-for-xxlarge,.hide-for-xxlarge-down{display:none !important}.hidden-for-small-only,.visible-for-small-up,.hidden-for-small,.hidden-for-small-down,.hidden-for-medium-only,.visible-for-medium-up,.hidden-for-medium,.hidden-for-medium-down,.hidden-for-large-only,.visible-for-large-up,.hidden-for-large,.hidden-for-large-down,.hidden-for-xlarge-only,.visible-for-xlarge-up,.hidden-for-xlarge,.hidden-for-xlarge-down,.visible-for-xxlarge-only,.visible-for-xxlarge-up,.visible-for-xxlarge,.visible-for-xxlarge-down{position:static !important;height:auto;width:auto;overflow:visible;clip:auto}.visible-for-small-only,.hidden-for-small-up,.visible-for-small,.visible-for-small-down,.visible-for-medium-only,.hidden-for-medium-up,.visible-for-medium,.visible-for-medium-down,.visible-for-large-only,.hidden-for-large-up,.visible-for-large,.visible-for-large-down,.visible-for-xlarge-only,.hidden-for-xlarge-up,.visible-for-xlarge,.visible-for-xlarge-down,.hidden-for-xxlarge-only,.hidden-for-xxlarge-up,.hidden-for-xxlarge,.hidden-for-xxlarge-down{position:absolute !important;height:1px;width:1px;overflow:hidden;clip:rect(1px, 1px, 1px, 1px)}table.hide-for-small-only,table.show-for-small-up,table.hide-for-small,table.hide-for-small-down,table.hide-for-medium-only,table.show-for-medium-up,table.hide-for-medium,table.hide-for-medium-down,table.hide-for-large-only,table.show-for-large-up,table.hide-for-large,table.hide-for-large-down,table.hide-for-xlarge-only,table.show-for-xlarge-up,table.hide-for-xlarge,table.hide-for-xlarge-down,table.show-for-xxlarge-only,table.show-for-xxlarge-up,table.show-for-xxlarge,table.show-for-xxlarge-down{display:table !important}thead.hide-for-small-only,thead.show-for-small-up,thead.hide-for-small,thead.hide-for-small-down,thead.hide-for-medium-only,thead.show-for-medium-up,thead.hide-for-medium,thead.hide-for-medium-down,thead.hide-for-large-only,thead.show-for-large-up,thead.hide-for-large,thead.hide-for-large-down,thead.hide-for-xlarge-only,thead.show-for-xlarge-up,thead.hide-for-xlarge,thead.hide-for-xlarge-down,thead.show-for-xxlarge-only,thead.show-for-xxlarge-up,thead.show-for-xxlarge,thead.show-for-xxlarge-down{display:table-header-group !important}tbody.hide-for-small-only,tbody.show-for-small-up,tbody.hide-for-small,tbody.hide-for-small-down,tbody.hide-for-medium-only,tbody.show-for-medium-up,tbody.hide-for-medium,tbody.hide-for-medium-down,tbody.hide-for-large-only,tbody.show-for-large-up,tbody.hide-for-large,tbody.hide-for-large-down,tbody.hide-for-xlarge-only,tbody.show-for-xlarge-up,tbody.hide-for-xlarge,tbody.hide-for-xlarge-down,tbody.show-for-xxlarge-only,tbody.show-for-xxlarge-up,tbody.show-for-xxlarge,tbody.show-for-xxlarge-down{display:table-row-group !important}tr.hide-for-small-only,tr.show-for-small-up,tr.hide-for-small,tr.hide-for-small-down,tr.hide-for-medium-only,tr.show-for-medium-up,tr.hide-for-medium,tr.hide-for-medium-down,tr.hide-for-large-only,tr.show-for-large-up,tr.hide-for-large,tr.hide-for-large-down,tr.hide-for-xlarge-only,tr.show-for-xlarge-up,tr.hide-for-xlarge,tr.hide-for-xlarge-down,tr.show-for-xxlarge-only,tr.show-for-xxlarge-up,tr.show-for-xxlarge,tr.show-for-xxlarge-down{display:table-row}th.hide-for-small-only,td.hide-for-small-only,th.show-for-small-up,td.show-for-small-up,th.hide-for-small,td.hide-for-small,th.hide-for-small-down,td.hide-for-small-down,th.hide-for-medium-only,td.hide-for-medium-only,th.show-for-medium-up,td.show-for-medium-up,th.hide-for-medium,td.hide-for-medium,th.hide-for-medium-down,td.hide-for-medium-down,th.hide-for-large-only,td.hide-for-large-only,th.show-for-large-up,td.show-for-large-up,th.hide-for-large,td.hide-for-large,th.hide-for-large-down,td.hide-for-large-down,th.hide-for-xlarge-only,td.hide-for-xlarge-only,th.show-for-xlarge-up,td.show-for-xlarge-up,th.hide-for-xlarge,td.hide-for-xlarge,th.hide-for-xlarge-down,td.hide-for-xlarge-down,th.show-for-xxlarge-only,td.show-for-xxlarge-only,th.show-for-xxlarge-up,td.show-for-xxlarge-up,th.show-for-xxlarge,td.show-for-xxlarge,th.show-for-xxlarge-down,td.show-for-xxlarge-down{display:table-cell !important}}.show-for-landscape,.hide-for-portrait{display:inherit !important}.hide-for-landscape,.show-for-portrait{display:none !important}table.hide-for-landscape,table.show-for-portrait{display:table !important}thead.hide-for-landscape,thead.show-for-portrait{display:table-header-group !important}tbody.hide-for-landscape,tbody.show-for-portrait{display:table-row-group !important}tr.hide-for-landscape,tr.show-for-portrait{display:table-row !important}td.hide-for-landscape,td.show-for-portrait,th.hide-for-landscape,th.show-for-portrait{display:table-cell !important}@media only screen and (orientation: landscape){.show-for-landscape,.hide-for-portrait{display:inherit !important}.hide-for-landscape,.show-for-portrait{display:none !important}table.show-for-landscape,table.hide-for-portrait{display:table !important}thead.show-for-landscape,thead.hide-for-portrait{display:table-header-group !important}tbody.show-for-landscape,tbody.hide-for-portrait{display:table-row-group !important}tr.show-for-landscape,tr.hide-for-portrait{display:table-row !important}td.show-for-landscape,td.hide-for-portrait,th.show-for-landscape,th.hide-for-portrait{display:table-cell !important}}@media only screen and (orientation: portrait){.show-for-portrait,.hide-for-landscape{display:inherit !important}.hide-for-portrait,.show-for-landscape{display:none !important}table.show-for-portrait,table.hide-for-landscape{display:table !important}thead.show-for-portrait,thead.hide-for-landscape{display:table-header-group !important}tbody.show-for-portrait,tbody.hide-for-landscape{display:table-row-group !important}tr.show-for-portrait,tr.hide-for-landscape{display:table-row !important}td.show-for-portrait,td.hide-for-landscape,th.show-for-portrait,th.hide-for-landscape{display:table-cell !important}}.show-for-touch{display:none !important}.hide-for-touch{display:inherit !important}.touch .show-for-touch{display:inherit !important}.touch .hide-for-touch{display:none !important}table.hide-for-touch{display:table !important}.touch table.show-for-touch{display:table !important}thead.hide-for-touch{display:table-header-group !important}.touch thead.show-for-touch{display:table-header-group !important}tbody.hide-for-touch{display:table-row-group !important}.touch tbody.show-for-touch{display:table-row-group !important}tr.hide-for-touch{display:table-row !important}.touch tr.show-for-touch{display:table-row !important}td.hide-for-touch{display:table-cell !important}.touch td.show-for-touch{display:table-cell !important}th.hide-for-touch{display:table-cell !important}.touch th.show-for-touch{display:table-cell !important}.print-only{display:none !important}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}.show-for-print{display:block}.hide-for-print{display:none}table.show-for-print{display:table !important}thead.show-for-print{display:table-header-group !important}tbody.show-for-print{display:table-row-group !important}tr.show-for-print{display:table-row !important}td.show-for-print{display:table-cell !important}th.show-for-print{display:table-cell !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}.hide-on-print{display:none !important}.print-only{display:block !important}.hide-for-print{display:none !important}.show-for-print{display:inherit !important}}@media print{.show-for-print{display:block}.hide-for-print{display:none}table.show-for-print{display:table !important}thead.show-for-print{display:table-header-group !important}tbody.show-for-print{display:table-row-group !important}tr.show-for-print{display:table-row !important}td.show-for-print{display:table-cell !important}th.show-for-print{display:table-cell !important}}.slick-slider{position:relative;display:block;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-ms-touch-action:pan-y;touch-action:pan-y;-webkit-tap-highlight-color:transparent}.slick-list{position:relative;overflow:hidden;display:block;margin:0;padding:0}.slick-list:focus{outline:none}.slick-list.dragging{cursor:pointer;cursor:hand}.slick-slider .slick-track,.slick-slider .slick-list{-webkit-transform:translate3d(0, 0, 0);-moz-transform:translate3d(0, 0, 0);-ms-transform:translate3d(0, 0, 0);-o-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0)}.slick-track{position:relative;left:0;top:0;display:block}.slick-track:before,.slick-track:after{content:"";display:table}.slick-track:after{clear:both}.slick-loading .slick-track{visibility:hidden}.slick-slide{float:left;height:100%;min-height:1px;display:none}[dir="rtl"] .slick-slide{float:right}.slick-slide img{display:block}.slick-slide.slick-loading img{display:none}.slick-slide.dragging img{pointer-events:none}.slick-initialized .slick-slide{display:block}.slick-loading .slick-slide{visibility:hidden}.slick-vertical .slick-slide{display:block;height:auto;border:1px solid transparent}.slick-loading .slick-list{background:#fff url("../img/ajax-loader.gif") center center no-repeat}.slick-prev,.slick-next{position:absolute;display:block;height:20px;width:20px;line-height:0;font-size:0;cursor:pointer;background:transparent;color:transparent;top:50%;margin-top:-10px;padding:0;border:none;outline:none}.slick-prev:hover,.slick-prev:focus,.slick-next:hover,.slick-next:focus{outline:none;background:transparent;color:transparent}.slick-prev:hover:before,.slick-prev:focus:before,.slick-next:hover:before,.slick-next:focus:before{opacity:1}.slick-prev.slick-disabled:before,.slick-next.slick-disabled:before{opacity:.25}.slick-prev:before,.slick-next:before{font-family:"FontAwesome";font-size:20px;line-height:1;color:#ba2619;opacity:.75;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.slick-prev{left:15px}[dir="rtl"] .slick-prev{left:auto;right:15px}.slick-prev:before{content:""}[dir="rtl"] .slick-prev:before{content:""}.slick-next{right:15px}[dir="rtl"] .slick-next{left:15px;right:auto}.slick-next:before{content:""}[dir="rtl"] .slick-next:before{content:""}.slick-slider{margin-bottom:30px}.slick-dots{margin:0;position:absolute;bottom:30px;list-style:none;display:block;text-align:center;padding:0;width:100%}.slick-dots li{position:relative;display:inline-block;height:20px;width:20px;margin:0 5px;padding:0;cursor:pointer}.slick-dots li button{border:0;background:transparent;display:block;height:20px;width:20px;outline:none;line-height:0;font-size:0;color:transparent;padding:5px;cursor:pointer}.slick-dots li button:hover,.slick-dots li button:focus{outline:none}.slick-dots li button:hover:before,.slick-dots li button:focus:before{opacity:1}.slick-dots li button:before{position:absolute;top:0;left:0;content:"";width:20px;height:20px;font-family:"FontAwesome";font-size:12px;line-height:20px;text-align:center;color:#000;opacity:.25;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.slick-dots li.slick-active button:before{color:#ba2619;opacity:.75}/*! * Font Awesome 4.4.0 by @davegandy - http://fontawesome.io - @fontawesome * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) */@font-face{font-family:'FontAwesome';src:url("./fonts/fontawesome-webfont.eot?v=4.4.0");src:url("./fonts/fontawesome-webfont.eot?#iefix&v=4.4.0") format("embedded-opentype"),url("./fonts/fontawesome-webfont.woff2?v=4.4.0") format("woff2"),url("./fonts/fontawesome-webfont.woff?v=4.4.0") format("woff"),url("./fonts/fontawesome-webfont.ttf?v=4.4.0") format("truetype"),url("./fonts/fontawesome-webfont.svg?v=4.4.0#fontawesomeregular") format("svg");font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.3333333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.2857142857em;text-align:center}.fa-ul{padding-left:0;margin-left:2.1428571429em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.1428571429em;width:2.1428571429em;top:.1428571429em;text-align:center}.fa-li.fa-lg{left:-1.8571428571em}.fa-border{padding:.2em .25em .15em;border:solid 0.08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-remove:before,.fa-close:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-gear:before,.fa-cog:before{content:""}.fa-trash-o:before{content:""}.fa-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-rotate-right:before,.fa-repeat:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before{content:""}.fa-check-circle:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-warning:before,.fa-exclamation-triangle:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-gears:before,.fa-cogs:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before{content:""}.fa-arrow-circle-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-save:before,.fa-floppy-o:before{content:""}.fa-square:before{content:""}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-unsorted:before,.fa-sort:before{content:""}.fa-sort-down:before,.fa-sort-desc:before{content:""}.fa-sort-up:before,.fa-sort-asc:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-legal:before,.fa-gavel:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-flash:before,.fa-bolt:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-paste:before,.fa-clipboard:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-unlink:before,.fa-chain-broken:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:""}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:""}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:""}.fa-euro:before,.fa-eur:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-rupee:before,.fa-inr:before{content:""}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:""}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:""}.fa-won:before,.fa-krw:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-turkish-lira:before,.fa-try:before{content:""}.fa-plus-square-o:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-institution:before,.fa-bank:before,.fa-university:before{content:""}.fa-mortar-board:before,.fa-graduation-cap:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:""}.fa-file-zip-o:before,.fa-file-archive-o:before{content:""}.fa-file-sound-o:before,.fa-file-audio-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before{content:""}.fa-ge:before,.fa-empire:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-send:before,.fa-paper-plane:before{content:""}.fa-send-o:before,.fa-paper-plane-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-hotel:before,.fa-bed:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-yc:before,.fa-y-combinator:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-tv:before,.fa-television:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.maxWidth{width:100%}.hidden{display:none}*{transition:all 0.15s ease}body{background-color:#333}body>main{padding:2.5rem 0;background-color:#fff}@media only screen and (max-width: 40em){body>main{padding:1.25rem 0}}body>main img{margin-bottom:1.25rem}@media only screen and (max-width: 40em){aside{margin-bottom:1.5rem}}@media only screen and (max-width: 40em){.row{overflow:hidden}}body>footer{background-color:#333;padding:2.5rem 0;color:#999}body>footer p,body>footer h1,body>footer h2,body>footer h3,body>footer h4,body>footer h5,body>footer h6{color:inherit}body>footer a{color:#e23424}code{font-size:85%;color:inherit !important;overflow-x:scroll;-webkit-overflow-scrolling:touch}pre.highlight{border:solid 1px #ddd;background:#fff;padding:1em;line-height:23px;margin-bottom:30px;white-space:pre;overflow-x:auto;word-break:inherit;word-wrap:inherit;background:#ffffff}@media only screen and (max-width: 40em){pre.highlight{overflow-x:scroll;-webkit-overflow-scrolling:touch}}pre.highlight code{background-color:transparent;border:none;padding:0}pre.highlight td{padding:8px 15px}pre.highlight .gl{background:#fafafa;border-right:1px solid #ddd;color:#999;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}pre.highlight .c{color:#999988;font-style:italic}pre.highlight .err{color:#a61717;background-color:#e3d2d2}pre.highlight .k{font-weight:bold}pre.highlight .o{font-weight:bold}pre.highlight .cm{color:#999988;font-style:italic}pre.highlight .cp{color:#999999;font-weight:bold}pre.highlight .c1{color:#999988;font-style:italic}pre.highlight .cs{color:#999999;font-weight:bold;font-style:italic}pre.highlight .gd{color:#000000;background-color:#ffdddd}pre.highlight .gd .x{color:#000000;background-color:#ffaaaa}pre.highlight .ge{font-style:italic}pre.highlight .gr{color:#aa0000}pre.highlight .gh{color:#999999}pre.highlight .gi{color:#000000;background-color:#ddffdd}pre.highlight .gi .x{color:#000000;background-color:#aaffaa}pre.highlight .go{color:#888888}pre.highlight .gp{color:#555555}pre.highlight .gs{font-weight:bold}pre.highlight .gu{color:#aaaaaa}pre.highlight .gt{color:#aa0000}pre.highlight .kc{font-weight:bold}pre.highlight .kd{font-weight:bold}pre.highlight .kp{font-weight:bold}pre.highlight .kr{font-weight:bold}pre.highlight .kt{color:#445588;font-weight:bold}pre.highlight .m{color:#009999}pre.highlight .s{color:#d14}pre.highlight .na{color:#008080}pre.highlight .nb{color:#0086B3}pre.highlight .nc{color:#445588;font-weight:bold}pre.highlight .no{color:#008080}pre.highlight .ni{color:#800080}pre.highlight .ne{color:#990000;font-weight:bold}pre.highlight .nf{color:#990000;font-weight:bold}pre.highlight .nn{color:#555555}pre.highlight .nt{color:#000080}pre.highlight .nv{color:#008080}pre.highlight .ow{font-weight:bold}pre.highlight .w{color:#bbbbbb}pre.highlight .mf{color:#009999}pre.highlight .mh{color:#009999}pre.highlight .mi{color:#009999}pre.highlight .mo{color:#009999}pre.highlight .sb{color:#d14}pre.highlight .sc{color:#d14}pre.highlight .sd{color:#d14}pre.highlight .s2{color:#d14}pre.highlight .se{color:#d14}pre.highlight .sh{color:#d14}pre.highlight .si{color:#d14}pre.highlight .sx{color:#d14}pre.highlight .sr{color:#009926}pre.highlight .s1{color:#d14}pre.highlight .ss{color:#990073}pre.highlight .bp{color:#999999}pre.highlight .vc{color:#008080}pre.highlight .vg{color:#008080}pre.highlight .vi{color:#008080}pre.highlight .il{color:#009999}kbd{display:inline-block;padding:3px 5px;font-size:11px;line-height:10px;color:#555;vertical-align:middle;background-color:#fcfcfc;border:solid 1px #ccc;border-bottom-color:#bbb;border-radius:3px;box-shadow:inset 0 -1px 0 #bbb}.social__icons{margin-bottom:10px}.social__icon{display:inline-block;margin-right:10px}.slider picture img{width:100%}.videoWrapper{position:relative;padding-top:56.25%;margin-bottom:1.25rem}.videoWrapper iframe{position:absolute;top:0;left:0;width:100%;height:100%}.icon{position:relative;top:1px;display:inline-block;width:16px;height:16px}.icon-color{border:1px solid #aaa}.icon-color-white{background-color:#fff}.icon-color-black{background-color:#000}.icon-color-red{background-color:#ba2619}.toc-header{margin-bottom:0}#toc{display:block;margin:1rem 0 0 0}#toc>ol{margin-left:0}#toc>ol>li{margin-bottom:0.5rem}#toc ol{list-style-type:none}.clickable-header{cursor:pointer}.clickable-header:hover{text-decoration:underline}.top-level-header{display:inline-block}.back-to-top{position:relative;margin-left:8px;cursor:pointer;top:-3px}.contentSearch{margin-bottom:30px}@media only screen and (max-width: 40em){.contentSearch{margin-bottom:5px}}.contentSearch-wrapper{position:relative}.contentSearch-wrapper.small-collapse{margin:0 !important}.liveSearch-field{margin-bottom:0 !important}.liveSearch-button{margin-bottom:0}.liveSearch-result-list{position:absolute;width:100%;height:auto;background:white;border:1px #ccc;border-style:none solid solid solid;z-index:99;margin:0;list-style-type:none}@media only screen and (max-width: 40em){.liveSearch-result-list{position:relative}}.liveSearch-result-list li a{-webkit-transition:all 0.15s ease;transition:all 0.15s ease;padding:4px 10px;display:block;width:100%;height:100%;line-height:1.2}.liveSearch-result-list li a:hover{background-color:#eee}.liveSearch-result-list li a:first-child{padding-top:8px}.liveSearch-result-list li a:last-child{padding-bottom:8px}.searchPage-result-list{line-height:1.2;list-style-type:none}.searchPage-result-list li{margin-bottom:20px}@media only screen and (max-width: 40em){.searchPage-result-list li{margin-bottom:15px}}.searchPage-result-list li a{font-weight:bold;color:#1a0dab}.searchPage-result-list li a:hover{color:#1a0dab;text-decoration:underline}.searchPage-result-list li .url{color:#006621}@media only screen and (max-width: 40em){.searchPage-result-list li .additionalInfo{display:none}}.article-list{margin:0;padding:0;list-style-type:none}.article-list header h1{font-size:1.5rem}article header{margin-bottom:0.5rem}article header h1{margin-bottom:0}article .meta{font-size:0.9em}.table-wrapper{width:100%;overflow-y:auto;_overflow:auto;margin:0 0 1em} diff --git a/docs/img/wiki/feature/m47_flank.png b/docs/img/wiki/feature/m47_flank.png new file mode 100644 index 0000000000..fbbf9c9403 Binary files /dev/null and b/docs/img/wiki/feature/m47_flank.png differ diff --git a/docs/img/wiki/feature/m47_fro_obl_fla.png b/docs/img/wiki/feature/m47_fro_obl_fla.png new file mode 100644 index 0000000000..bbd3013d8b Binary files /dev/null and b/docs/img/wiki/feature/m47_fro_obl_fla.png differ diff --git a/docs/img/wiki/feature/m47_frontal.png b/docs/img/wiki/feature/m47_frontal.png new file mode 100644 index 0000000000..48730b02c8 Binary files /dev/null and b/docs/img/wiki/feature/m47_frontal.png differ diff --git a/docs/img/wiki/feature/m47_oblique_45.png b/docs/img/wiki/feature/m47_oblique_45.png new file mode 100644 index 0000000000..616940aba7 Binary files /dev/null and b/docs/img/wiki/feature/m47_oblique_45.png differ diff --git a/docs/img/wiki/feature/m47_oblique_60.png b/docs/img/wiki/feature/m47_oblique_60.png new file mode 100644 index 0000000000..65c3cd23eb Binary files /dev/null and b/docs/img/wiki/feature/m47_oblique_60.png differ diff --git a/docs/src/package-lock.json b/docs/src/package-lock.json index e68f8ff216..154f69dca7 100644 --- a/docs/src/package-lock.json +++ b/docs/src/package-lock.json @@ -425,7 +425,7 @@ }, "p-cancelable": { "version": "0.4.1", - "resolved": "http://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==", "dev": true, "optional": true @@ -496,7 +496,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "optional": true, @@ -512,7 +512,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "optional": true, @@ -1135,14 +1135,14 @@ "dependencies": { "file-type": { "version": "3.9.0", - "resolved": "http://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=", "dev": true, "optional": true }, "get-stream": { "version": "2.3.1", - "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", "dev": true, "optional": true, @@ -1251,7 +1251,7 @@ "dependencies": { "domelementtype": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", "dev": true, "optional": true @@ -1394,9 +1394,9 @@ "dev": true }, "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, "eventemitter2": { @@ -1872,7 +1872,7 @@ }, "get-stream": { "version": "3.0.0", - "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", "dev": true, "optional": true @@ -2093,9 +2093,9 @@ "optional": true }, "grunt": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.0.3.tgz", - "integrity": "sha512-/JzmZNPfKorlCrrmxWqQO4JVodO+DVd5XX4DkocL/1WlLlKVLE9+SdEIempOAxDhWPysLle6afvn/hg7Ck2k9g==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.0.4.tgz", + "integrity": "sha512-PYsMOrOC+MsdGEkFVwMaMyc6Ob7pKmq+deg1Sjr+vvMWp35sztfwKE7qoN51V+UEtHsyNuMcGdgMLFkBHvMxHQ==", "dev": true, "requires": { "coffeescript": "~1.10.0", @@ -2109,7 +2109,7 @@ "grunt-legacy-log": "~2.0.0", "grunt-legacy-util": "~1.1.1", "iconv-lite": "~0.4.13", - "js-yaml": "~3.5.2", + "js-yaml": "~3.13.0", "minimatch": "~3.0.2", "mkdirp": "~0.5.1", "nopt": "~3.0.6", @@ -2128,15 +2128,6 @@ "nopt": "~3.0.6", "resolve": "~1.1.0" } - }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, - "requires": { - "glob": "^7.0.5" - } } } }, @@ -2302,9 +2293,9 @@ } }, "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -2626,7 +2617,7 @@ }, "is-accessor-descriptor": { "version": "0.1.6", - "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { @@ -2663,7 +2654,7 @@ }, "is-data-descriptor": { "version": "0.1.4", - "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { @@ -2887,13 +2878,13 @@ } }, "js-yaml": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.5.5.tgz", - "integrity": "sha1-A3fDgBfKvHMisNH7zSWkkWQfL74=", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", "dev": true, "requires": { - "argparse": "^1.0.2", - "esprima": "^2.6.0" + "argparse": "^1.0.7", + "esprima": "^4.0.0" } }, "json-buffer": { @@ -2942,9 +2933,9 @@ } }, "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.13.tgz", + "integrity": "sha512-vm3/XWXfWtRua0FkUyEHBZy8kCPjErNBT9fJx8Zvs+U6zjqPbTUOpkaoum3O5uiA8sm+yNMHXfYkTUHFoMxFNA==" }, "logalot": { "version": "2.1.0", @@ -3156,9 +3147,9 @@ "dev": true }, "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "dev": true, "requires": { "for-in": "^1.0.2", @@ -3688,7 +3679,7 @@ "dependencies": { "string_decoder": { "version": "0.10.31", - "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true } @@ -3806,6 +3797,31 @@ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + }, + "dependencies": { + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", @@ -3875,9 +3891,9 @@ } }, "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", "dev": true, "requires": { "extend-shallow": "^2.0.1", @@ -4270,17 +4286,10 @@ "util.promisify": "~1.0.0" }, "dependencies": { - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "optional": true - }, "js-yaml": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", - "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", "dev": true, "optional": true, "requires": { @@ -4462,38 +4471,15 @@ } }, "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", "dev": true, "requires": { "arr-union": "^3.1.0", "get-value": "^2.0.6", "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } + "set-value": "^2.0.1" } }, "unquote": { diff --git a/docs/src/package.json b/docs/src/package.json index 8e98082823..5a7586ac7e 100644 --- a/docs/src/package.json +++ b/docs/src/package.json @@ -2,10 +2,10 @@ "name": "ACE3", "version": "0.1.0", "dependencies": { - "lodash": "^4.17.11" + "lodash": "^4.17.13" }, "devDependencies": { - "grunt": "^1.0.3", + "grunt": "^1.0.4", "grunt-contrib-concat": "^1.0.1", "grunt-contrib-imagemin": "^3.1.0", "grunt-contrib-uglify": "^4.0.0", diff --git a/docs/wiki/development/coding-guidelines.md b/docs/wiki/development/coding-guidelines.md index 23ad2317f9..370a10275c 100644 --- a/docs/wiki/development/coding-guidelines.md +++ b/docs/wiki/development/coding-guidelines.md @@ -126,7 +126,8 @@ These macros are allowed but are not enforced. |`GETVAR(player,MyVarName,false)` | `player getVariable ["MyVarName", false]` | |`GETMVAR(MyVarName,objNull)` | `missionNamespace getVariable ["MyVarName", objNull]` | |`GETUVAR(MyVarName,displayNull)` | `uiNamespace getVariable ["MyVarName", displayNull]` | -|`SETVAR(player,MyVarName,127)` | `player setVariable ["MyVarName", 127] SETPVAR(player,MyVarName,127) player setVariable ["MyVarName", 127, true]` | +|`SETVAR(player,MyVarName,127)` | `player setVariable ["MyVarName", 127]` | +|`SETPVAR(player,MyVarName,127)` | `player setVariable ["MyVarName", 127, true]` | |`SETMVAR(MyVarName,player)` | `missionNamespace setVariable ["MyVarName", player]` | |`SETUVAR(MyVarName,_control)` | `uiNamespace setVariable ["MyVarName", _control]` | diff --git a/docs/wiki/development/extension-guidelines.md b/docs/wiki/development/extension-guidelines.md index f4dc6e40bd..d7f4fe08a6 100644 --- a/docs/wiki/development/extension-guidelines.md +++ b/docs/wiki/development/extension-guidelines.md @@ -58,3 +58,36 @@ extensions\ ``` ### 2.2 Creating a new Extension + +#### 2.2.1 Arma Config + +ACE3 loads extensions defined in `ACE_Extensions` root config class and supports the following entries: + +```cpp +// Platform +windows = 1; // Load on Windows +linux = 1; // Load on Linux + +// Type +client = 1; // Load on Client +server = 1; // Load on Server +``` + +```cpp +class ACE_Extensions { + // Windows Client only extension + class tag_extension { + windows = 1; + client = 1; + }; + + // Any platform Server extension + class tag_extension2 { + windows = 1; + linux = 1; + server = 1; + }; +}; +``` + +Combining platform and client/server values is possible to get all combinations currently supported by the game and more. diff --git a/docs/wiki/development/setting-up-the-development-environment.md b/docs/wiki/development/setting-up-the-development-environment.md index 4de655102d..cc5b5192da 100644 --- a/docs/wiki/development/setting-up-the-development-environment.md +++ b/docs/wiki/development/setting-up-the-development-environment.md @@ -13,12 +13,13 @@ This page describes how you can setup your development environment for ACE3, all ## 1. Requirements - Arma 3 -- A proper installation of the Arma 3 Tools (available on Steam) -- A properly setup P-drive +- Arma 3 Tools (available on Steam) +- P-drive - Run Arma 3 and Arma 3 Tools directly from steam once to install registry entries (and again after every update) - [Python 3.x](https://www.python.org/) -- [Mikero Tools](https://armaservices.maverick-applications.com/Products/MikerosDosTools/FileBrowserFree): DePbo, DeRap, DeOgg, Rapify, MakePbo, PboProject >=1.70 -- `*.hpp` removed from PboProject's "Exclude From Pbo" list +- [Mikero Tools](https://mikero.bytex.digital/Downloads): DePbo, DeOgg, Rapify, MakePbo, PboProject >=1.70 + - `*.hpp` removed from PboProject's "Exclude From Pbo" list + - `-F rebuild RequiredAddons` disabled - Python, Mikero Tools and Git in PATH environment variable - [CBA](https://github.com/CBATeam/CBA_A3/releases/latest) mod (release or development version) diff --git a/docs/wiki/feature/atragmx.md b/docs/wiki/feature/atragmx.md index d3126e0ba5..e17f783b5d 100644 --- a/docs/wiki/feature/atragmx.md +++ b/docs/wiki/feature/atragmx.md @@ -89,7 +89,7 @@ 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 module]({{ 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). +- 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) - Open the `Gun` column, check and update the `Zero Range` and `Done`. @@ -128,12 +128,16 @@ Horus ATragMX software considers atmospheric conditions, gun data, ammunition, r - [ATragMX Framework]({{ site.baseurl }}/wiki/framework/atragmx.html) - -## 4. Official Manual and Horus Videos +### 3.7 Reseting the AtragMx `GunList` + +- Open the Eden Editor and the Extended Debug Console (Ctrl+D). +- Execute `call ace_atragmx_fnc_clear_user_data` (LOCAL EXEC). +- The original ACE3 `GunList` will be restored (all `Add New Gun` entries deleted). + + +## 4. Official References - [Official Manual]({{ site.ace.githubUrl }}/blob/master/extras/manual_Horus_ATrag-v385.pdf) -- [Horus video part1](https://www.youtube.com/watch?v=pg6oqT5jVds) -- [Horus video part2](https://www.youtube.com/watch?v=7SkRnbwoPmw) ## 5. Dependencies diff --git a/docs/wiki/feature/crew-served-weapons.md b/docs/wiki/feature/crew-served-weapons.md new file mode 100644 index 0000000000..33a01bb460 --- /dev/null +++ b/docs/wiki/feature/crew-served-weapons.md @@ -0,0 +1,78 @@ +--- +layout: wiki +title: Crew Served Weapons +description: Static weapons that require multiple people to crew +group: feature +category: equipment +parent: wiki +mod: ace +version: + major: 3 + minor: 13 + patch: 0 +--- + +## 1. Overview + +Crew Served Weapons are static weapons that require multiple people to crew them. + +### 1.1 Loading/Unloading of ammo into static weapons + +Static weapons need to be manually loaded with ammo when placed down. The user can also unload ammo from static weapons, and place the ammo into their inventory for transport + +### 1.2 Assembling/Disassembling of static weapons + +Static weapons are assembled when a tripod is placed down, and the weapon mounted ontop. The user can then disassemble the weapon back into the tripod and weapon-bag and carry it around for the next deployment. + +## 2. Usage + +### 2.1 Loading Ammo + +- Apporach the static weapon with the relavent ammo in your inventory +- Interact with the weapon using ⊞ Win (ACE3 default) and navigate to the `CSW` menu. +- Select `Handle Ammo` +- Select `Load X` where X is the ammo you want loaded and wait for the timer to complete + +### 2.2 Unloading ammo + +- Apporach the static weapon and interact ⊞ Win (ACE3 default) +- Navigate to the `CSW` menu +- Select `Unload Ammo` and wait for the timer to complete +- The ammo will be placed to the left of the gun + +### 2.3 Assembling Weapon + +- Have the tripod and the relavent weapon in your launcher slot +- Place down tripod in the self-interact menu Ctrl + ⊞ Win (ACE3 default) +- Approach the tripod with the wanted weapon, and interact ⊞ Win (ACE3 default) +- Navigate to the `CSW` menu, and select `Assemble Weapon` +- Wait for the timer to complete, and the weapon will be assembled in the direction the tripod is facing + +### 2.4 Disassembling Weapon + +- Approach the static weapon and interact ⊞ Win (ACE3 default) +- Navigate to the `CSW` menu +- Select `Disassemble Weapon` +- Wait for the timer to complete +- The tripod, ammo, and weapon will spawn where the static weapon was + +## 3. Addon Options + +### 3.1 defaultAssemblyMode + +- Enables/Disables the ability to assemble the CSW through the addon (Non-Vanilla assembly) +- Default: Off + +### 3.2 handleExtraMagazines + +- Enables/Disables the magazines in the CSW will appear next to the gun on weapon initialization when using defaultAssemblyMode and you have a pre-placed static weapon +- Default: On + +### 3.3 ammoHandling + +- Whether or not you want to handle ammo using the CSW way. Does nothing if using defaultAssemblyMode +- Default: On + +## 4. Dependencies + +{% include dependencies_list.md component="csw" %} diff --git a/docs/wiki/feature/dragon.md b/docs/wiki/feature/dragon.md new file mode 100644 index 0000000000..6a3e75becb --- /dev/null +++ b/docs/wiki/feature/dragon.md @@ -0,0 +1,80 @@ +--- +layout: wiki +title: M47 Dragon Missile +description: M47 Dragon +group: feature +category: equipment +parent: wiki +mod: ace +version: + major: 3 + minor: 13 + patch: 0 +--- + +## 1. Overview + +### 1.1 Guidance + +The M47 Dragon is a wire-guided SACLOS missile with a unique manuever system. It has a series of charges along the missile that fire every third of a second to adjust the missile on course + +### 1.2 Attack profiles + +The missile requires line of sight to the target at all times. Keep your crosshair on the target as the missile cruises toward it until impact. +If you lose line of sight the missile will stop tracking toward your crosshair and will fly on its current trajectory. You can regain control if the missile re-enters line of sight. +If the missile exceeds its maximum range the wire will snap and it will fly off in a random direction. +The missiles manuever system causes inaccuracy that cannot be corrected for by the gunner. This means that the risk of missing increases as range goes up + +## 2. Usage + +### 2.1 Placement + +- Ensure that you have the M47 Super-Dragon launcher as well as the SU-36/P sighting unit +- Use self interaction Ctrl+⊞ Win (ACE3 default key bind `Self Interaction Key`) +- Select 'Place Tripod' +- Interact with the missile ⊞ Win (ACE3 default key bind `Interaction Key`) +- Select 'Attach Sight' +- Get into the launcher +- Point at target +- Fire + +### 2.2 Tear Down +- Interact with the missile ⊞ Win (ACE3 default key bind `Interaction Key`) +- Select 'Disassemble' +- Look to the right of the launcher and pick up the sighting unit +- Move on + +## 3. Sight Ranging + +The Dragon gunners use the stadia lines in the daysight to determine if a target falls within range. Moving and stationary vehicles may present flank, oblique, and frontal or rear targets (Figure 1). +At maximum range (1,500 meters), a 7-meter (23-foot) long target completely fills the area between the stadia lines and exceeds the stadia lines at a closer range. + +**Figure 1. Frontal, oblique, and flank targets** +Frontal, Oblique, and Flank targets + +### 3.1 **Flanking Targets (Full Stadia)** + +Adjust the sight picture by moving the launcher so the target centers between the stadia lines (Figure 2). + +**Figure 2. Range determination for flank target.** +Frontal, Oblique, and Flank targets + +### 3.2 **Oblique Targets** + +If you can see more of the flank, use the full-stadia method (Figure 3.1). The vehicle should appear to fill the area between the stadia lines. If you see more of the front or rear, use the half-stadia method (Figure 3.2). The track of the vehicle should fit between one stadia line and the center. + +**Figure 3.1. Range determination for oblique target, more flank visible** +Frontal, Oblique, and Flank targets +**Figure 3.2. Range determination for oblique target, more front or rear visible** +Frontal, Oblique, and Flank targets + +### 3.3 **Frontal (Head-On) or Rear (Going Away, Half-Stadia) Targets** + +Adjust the sight picture by moving the launcher to align the vertical cross hair and one of the stadia lines on the target (Figure 4) + +**Figure 4. Range determination for frontal or rear target.** +Frontal, Oblique, and Flank targets + +## 4. Dependencies + +{% include dependencies_list.md component="dragon" %} diff --git a/docs/wiki/feature/scopes.md b/docs/wiki/feature/scopes.md index 3eab4a1de0..a5b30ee36b 100644 --- a/docs/wiki/feature/scopes.md +++ b/docs/wiki/feature/scopes.md @@ -33,7 +33,7 @@ Please not that the following key combinations are ACE3 default key binds. - Major adjustment right Ctrl + ⇧ Shift + Page Up. - Major adjustment left Ctrl + ⇧ Shift + page Down. -### 2.3 Scopes Module +### 2.3 Scopes Options CBA Settings scopes module diff --git a/docs/wiki/framework/cargo-framework.md b/docs/wiki/framework/cargo-framework.md index 7f009b4efa..38e0d6d267 100644 --- a/docs/wiki/framework/cargo-framework.md +++ b/docs/wiki/framework/cargo-framework.md @@ -118,6 +118,7 @@ Note first arg can be a in-game object or a classname of an object type. * Arguments: * 0: Item * 1: Vehicle + * 2: Ignore interaction distance and stability checks * * Return Value: * Object loaded diff --git a/docs/wiki/framework/crew-served-weapons-framework.md b/docs/wiki/framework/crew-served-weapons-framework.md new file mode 100644 index 0000000000..3f64b09587 --- /dev/null +++ b/docs/wiki/framework/crew-served-weapons-framework.md @@ -0,0 +1,147 @@ +--- +layout: wiki +title: Crew Served Weapons Framework +description: Explains how to add new Crew Served Weapons to ACE3 +group: framework +order: 5 +parent: wiki +mod: ace +version: + major: 3 + minor: 13 + patch: 0 +--- + +## 1. Making a new Crew Served Weapon + +### 1.1 CfgVehicles + +```cpp +class CfgVehicles { + class LandVehicle; + class StaticWeapon: LandVehicle { + class ACE_Actions; + }; + class StaticMGWeapon: StaticWeapon { + class Turrets { + class MainTurret; + }; + class ACE_Actions: ACE_Actions { + class ACE_MainActions; + }; + }; + class banana_csw: StaticMGWeapon { + class ace_csw { + enabled = 1; // whether or not the weapon is affected by CSW + proxyWeapon = QGVAR(HMG_Static); // The weapon that will be added to the CSW on initialization. Used to ensure lower ammo-reload time when using Ammo Handling + magazineLocation = "_target selectionPosition 'magazine'"; // The location of the magazine. Where the action for ammo-handling will appear on the weapon + disassembleWeapon = QGVAR(staticHMGCarry); // What the weapon will disassemble to + disassembleTurret = QGVAR(m3TripodLow); // Which tripod will appear when weapon has been disassembled + ammoLoadTime = 7; // How long it takes in seconds to load ammo into the weapon + ammoUnloadTime = 5; // How long it takes in seconds to unload ammo from the weapon + desiredAmmo = 69; // When the weapon is reloaded it will try and reload to this ammo capacity + disassembleFunc = "myCoolFunction.sqf"; // A callback function for when the CSW gets disassembled. Arguments: [tripod, staticWeapon] + }; + }; +}; +``` + +### 1.2 CfgMagazines + +```cpp +class CfgMagazines { + class 100Rnd_127x99_mag; // Example magazine used - does not have to be this + class banana_ammo: 100Rnd_127x99_mag { + scope=2; // Needs to be 2 to make sure it shows up in Arsenal + type=256; // Must be 256 to show up in Arsenal + count = 100; // How much ammo gets added per "Load Ammo" selection + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; // default ammo box model + //ace_isbelt = 1; // Needed if your magazine has belt linking + }; +}; +``` + +### 1.3 CfgWeapons + +```cpp +class CfgWeapons { + class Launcher_Base_F; + class banana_carry_weapon: Launcher_Base_F { + class ACE_CSW { + type = "weapon"; // What type of carry it is. Must always be "weapon" for the carry weapon + deployTime = 4; // How long it takes to deploy the weapon onto the tripod + pickupTime = 4; // How long it takes to disassemble weapon from the tripod + class assembleTo { + ace_csw_m3Tripod = "banana_csw_mod1"; // What tripod can this weapon deploy onto, and what vehicle will it spawn when it is deployed + banana_tripod = "banana_csw"; + }; + }; + }; + + class HMG_Static; + class banana_proxy_weapon: HMG_Static { + magazineReloadTime = 0.5; // Proxy weapons are spawned onto the CSW when it is assembled. Because ammo loading times use defined values in the magazine, this number needs to be low to ensure low latency + }; +}; +``` + +### 1.4 CfgMagazineGroups + +```cpp + class ace_csw_groups { // Ammo that can be loaded into this CSW + class banana_ammo { // The magazine which the player can place into their inventory + banana_dummy_ammo = 1; // Magazine that is loaded into the weapon as per CfgWeapons >> weapon >> magazines + }; + + // Optional + class ace_csw_100Rnd_127x99_mag { // default magazine that CSW already implements + banana_dummy_ammo = 1; + }; + + /* + Ammo types already defined by CSW: + - ace_csw_100Rnd_127x99_mag + - ace_csw_100Rnd_127x99_mag_red + - ace_csw_100Rnd_127x99_mag_green + - ace_csw_100Rnd_127x99_mag_yellow + - ace_csw_50Rnd_127x108_mag + - ace_csw_20Rnd_20mm_G_belt + - ACE_1Rnd_82mm_Mo_HE + - ACE_1Rnd_82mm_Mo_Smoke + - ACE_1Rnd_82mm_Mo_Illum + - ACE_1Rnd_82mm_Mo_HE_Guided + - ACE_1Rnd_82mm_Mo_HE_LaserGuided + - Titan_AT + - Titan_AA + */ + }; +``` + +## 2. Making a new Tripod + +### 2.1 CfgVehicles + +```cpp +class CfgVehicles { + class ace_csw_baseTripod; + class banana_tripod: ace_csw_baseTripod { + class ace_csw { disassembleTo = "banana_carry_tripod"; }; // What will be spawned when "Pickup Tripod" is selected + }; +}; +``` + +### 2.2 CfgWeapons + +```cpp +class CfgWeapons { + class Launcher_Base_F; + class banana_carry_tripod: Launcher_Base_F { + class ACE_CSW { + type = "mount"; // What type of carry it is. Must always be "mount" for the tripod + deployTime = 4; // How long it takes to deploy the tripod + pickupTime = 4; // How long it takes to pickup the tripod + deploy = "banana_tripod"; // what vehicle will spawn when the tripod is deployed + }; + }; +}; +``` diff --git a/docs/wiki/framework/events-framework.md b/docs/wiki/framework/events-framework.md index 7a1481a299..f4f0cf9fae 100644 --- a/docs/wiki/framework/events-framework.md +++ b/docs/wiki/framework/events-framework.md @@ -89,6 +89,14 @@ MenuType: 0 = Interaction, 1 = Self Interaction |----------|---------|---------|---------|---------|---------| |`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 + ## 3. Usage Also Reference [CBA Events System](https://github.com/CBATeam/CBA_A3/wiki/Custom-Events-System){:target="_blank"} documentation. diff --git a/docs/wiki/framework/grenades-framework.md b/docs/wiki/framework/grenades-framework.md new file mode 100644 index 0000000000..a0b0ceeea7 --- /dev/null +++ b/docs/wiki/framework/grenades-framework.md @@ -0,0 +1,70 @@ +--- +layout: wiki +title: Grenades Framework +description: Explains how to set-up flashbangs, particularly multi-bangs. +group: framework +parent: wiki +order: 7 +mod: ace +version: + major: 3 + minor: 13 + patch: 0 +--- + +## 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)`. + + +## 2. 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 +class CfgAmmo { + class MyDefaultFlashbang { + ace_grenades_flashbang = 1; // A flashbang + ace_grenades_flashbangBangs = 1; // with one bang + ace_grenades_flashbangInterval = 0.5; // 0.5 seconds between each subsequent bang + ace_grenades_flashbangIntervalMaxDeviation = 0.1; // Deviation of up to ± 0.1 seconds on each fuse + }; + class ACE_G_M84 { + explosionTime = 2.3; // Seconds until the initial explosion + timeToLive = 6; // Seconds until the projectile is removed + ace_grenades_flashbang = 1; // A normal flashbang + }; + class ACE_G_CTS9 { + explosionTime = 1.5; + timeToLive = 10; + ace_grenades_flashbang = 1; + ace_grenades_flashbangBangs = 9; // 9 bangs + ace_grenades_flashbangInterval = 0.5; // 0.5 seconds between each subsequent bang + ace_grenades_flashbangIntervalMaxDeviation = "0.1 * sqrt (12*4) / 2"; // Standard deviation of 0.1 seconds on each fuse + }; + class 16aa_Ammo_6Bang { // British Armed Forces L107A1 + explosionTime = 1; + timeToLive = 5; + ace_grenades_flashbang = 1; + 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 + }; +}; +``` + +### 2.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 + +The flashbang will explode as many times as is specified. The default is 1. + +### 2.3 ace_grenades_flashbangInterval + +The average amount of time in seconds, after `explosionTime` has passed, between each subsequent bang. + +### 2.4 ace_grenades_flashbangIntervalMaxDeviation + +The amount of randomness in the fuse time. diff --git a/docs/wiki/framework/gunbag-framework.md b/docs/wiki/framework/gunbag-framework.md new file mode 100644 index 0000000000..a3df099abe --- /dev/null +++ b/docs/wiki/framework/gunbag-framework.md @@ -0,0 +1,39 @@ +--- +layout: wiki +title: Gunbag Framework +description: Explains how to set up gunbags +group: framework +parent: wiki +order: 7 +mod: ace +version: + major: 3 + minor: 13 + patch: 0 +--- + +## 1. Overview + +ACE Gunbag provides a framework that allows users to enable putting a gun inside a backpack. + + +## 2. Config Values + +The `ace_gunbag` config entry needs to be set to `1` to enable a backpack to be a gunbag. + +```cpp +class Bag_Base; +class ace_gunbag: Bag_Base { + author = "Ir0n1E"; + scope = 2; + displayName = CSTRING(Displayname); + model = QPATHTOF(data\ace_gunbag.p3d); + picture = QPATHTOF(ui\gunbag_ca.paa); + icon = QPATHTOF(ui\gunbag_icon_ca.paa); + hiddenSelections[] = {"Camo", "insignia"}; + hiddenSelectionsTextures[] = {QPATHTOF(data\gunbag_co.paa)}; + maximumLoad = 80; + mass = 11; + ace_gunbag = 1; +}; +``` diff --git a/docs/wiki/framework/interactionMenu-framework.md b/docs/wiki/framework/interactionMenu-framework.md index 069baf351c..54cb1fed38 100644 --- a/docs/wiki/framework/interactionMenu-framework.md +++ b/docs/wiki/framework/interactionMenu-framework.md @@ -21,7 +21,7 @@ Something the user would do to themselves or to their vehicle (eg. Put in ear pl - **Zeus** (`ACE_ZeusActions`) Available to Zeus -`ACE_Actions` and `ACE_SelfActions` can be added via config or by calling functions, it is generally preferred to add actions via config. Zeus actions can only be added via config. +`ACE_Actions` and `ACE_SelfActions` can be added via config or by calling functions. Be aware that the functions modify the UI, and therefore need to be executed on client-side to take effect. The simplest action is just a condition and statement. The code to these are passed `[_target, _player, _actionParams]`. `_player` is `ace_player`; `_target` is the object being interacted with; and the 3rd argument is the optional action parameters (default `[]`). diff --git a/docs/wiki/frameworkx/fortify-framework.md b/docs/wiki/frameworkx/fortify-framework.md index 045bc30e1a..3234ef2797 100644 --- a/docs/wiki/frameworkx/fortify-framework.md +++ b/docs/wiki/frameworkx/fortify-framework.md @@ -33,7 +33,7 @@ There are two ways of adding custom presets to your mission, either via code or To add a preset via code you use the function `call acex_fortify_fnc_registerObjects`. Also enables Fortify. -``` +```cpp * Registers the given objects in the given side's player interaction menu. * Players on that side must have the `Fortify Tool` item in their inventory to access the menu. * Classnames must be in the format [, ] @@ -53,7 +53,7 @@ To add a preset via code you use the function `call acex_fortify_fnc_registerObj Adding it through `description.ext` you use: -```c++ +```cpp class ACEX_Fortify_Presets { class myMissionObjects { objects[] = { @@ -63,15 +63,15 @@ class ACEX_Fortify_Presets { }; ``` - Then you will have to set the mission preset to `myMissionObjects` with `#fortify blufor myMissionObjects` to enable it. + Then you will have to set the mission preset to `myMissionObjects` with `#ace-fortify blufor myMissionObjects` to enable it. ## 1.3 Adding custom deploy handlers A custom deploy handler allows missions makers to decide if an object can be placed or not. -To verify that an object isn't above a certain terrain height we can check the heigt of the object before it is confirmed as placed. Returning `false` from the code block means that placement is not allowed. +To verify that an object isn't above a certain terrain height we can check the height of the object before it is confirmed as placed. Returning `false` from the code block means that placement is not allowed. -```sqf +```cpp [{ params ["_unit", "_object", "_cost"]; private _return = (getPosATL _object) select 2 < 1; diff --git a/docs/wiki/user/information-center.md b/docs/wiki/user/information-center.md index fa6077ee3e..8f828c6980 100644 --- a/docs/wiki/user/information-center.md +++ b/docs/wiki/user/information-center.md @@ -30,7 +30,7 @@ Downloaded ACE3 and have no idea where to start? This page serves as a starting ### 1.2 Issues -**Q:** Experiencing DLL errors. +**Q:** Experiencing extension errors. **A:** Start the game once with the Arma 3 Launcher, close it, then start the game with your usual launcher (ArmA3Sync, Play withSix, etc …). >The simple explanation is that the BattlEye process wasn't ended properly and is unable to start again properly, launching it with the Arma 3 Launcher is the only known solution to fix it. diff --git a/extensions/CMakeLists.txt b/extensions/CMakeLists.txt index ef6d8f8ded..0ac2fa5061 100644 --- a/extensions/CMakeLists.txt +++ b/extensions/CMakeLists.txt @@ -8,8 +8,8 @@ add_definitions(/DWINVER=0x0600 /D_WIN32_WINNT=0x0600) endif() if (NOT CMAKE_BUILD_TYPE AND CMAKE_COMPILER_IS_GNUCXX) - message(STATUS "No build type selected, default to Debug") - set(CMAKE_BUILD_TYPE "Debug") + message(STATUS "No build type selected, default to Debug") + set(CMAKE_BUILD_TYPE "Debug") endif() option(DEVEL "DEVEL" OFF) @@ -18,19 +18,29 @@ option(USE_DIRECTX "USE_DIRECTX" OFF) option(USE_64BIT_BUILD "USE_64BIT_BUILD" OFF) option(USE_STATIC_LINKING "USE_STATIC_LINKING" ON) +if(CMAKE_GENERATOR_PLATFORM MATCHES "x64") + set(USE_64BIT_BUILD ON) +endif() if(CMAKE_COMPILER_IS_GNUCXX) - SET(CMAKE_CXX_FLAGS "-std=c++11 -pedantic -pedantic-errors -march=i686 -m32 -O2 -s -fPIC -fpermissive") - set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") - set(CMAKE_SHARED_LINKER_FLAGS "-static-libgcc -static-libstdc++") + SET(CMAKE_CXX_FLAGS "-std=c++11 -pedantic -pedantic-errors -march=i686 -m32 -O2 -s -fPIC -fpermissive") + set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") + set(CMAKE_SHARED_LINKER_FLAGS "-static-libgcc -static-libstdc++") elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") message(ERROR "SUPPORT NOT COMPLETE") elseif (CMAKE_CXX_COMPILER_ID MATCHES "MSVC") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /arch:SSE2 /Qpar-report:2") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} /D _DEBUG /MTd /Zi /Ob0 /Od /RTC1") - set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS} /MT /O1 /Ob1 /D NDEBUG") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} /MT /O2 /Ob2 /D NDEBUG") - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS} /MT /Zi /O2 /Ob1 /D NDEBUG") + add_definitions(-D_CRT_SECURE_NO_WARNINGS) # Disable MSVC *_s function warnings + + if(USE_64BIT_BUILD) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /Qpar-report:2") # Default SSE2 + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /arch:SSE2 /Qpar-report:2") + endif() + + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} /D _DEBUG /MTd /Zi /Ob0 /Od /RTC1") + set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS} /MT /O1 /Ob1 /D NDEBUG") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} /MT /O2 /Ob2 /D NDEBUG") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS} /MT /Zi /O2 /Ob1 /D NDEBUG") endif() include_directories("common") diff --git a/extensions/advanced_ballistics/AdvancedBallistics.cpp b/extensions/advanced_ballistics/AdvancedBallistics.cpp index b77c412b35..6ea8d1fdea 100644 --- a/extensions/advanced_ballistics/AdvancedBallistics.cpp +++ b/extensions/advanced_ballistics/AdvancedBallistics.cpp @@ -254,7 +254,7 @@ double calculateAdvancedZero(double zeroRange, double muzzleVelocity, double bor double v = 0.0f; while (tof < 8.0f && px < zeroRange) { - lx = px; + lx = px; ly = py; v = std::sqrt(vx*vx + vy*vy); @@ -295,7 +295,7 @@ extern "C" void __stdcall RVExtensionVersion(char *output, int outputSize) { - strncpy_s(output, outputSize, ACE_FULL_VERSION_STR, _TRUNCATE); + strncpy(output, ACE_FULL_VERSION_STR, outputSize); } void __stdcall RVExtension(char *output, int outputSize, const char *function) @@ -303,7 +303,7 @@ void __stdcall RVExtension(char *output, int outputSize, const char *function) ZERO_OUTPUT(); std::stringstream outputStr; if (!strcmp(function, "version")) { - strncpy_s(output, outputSize, ACE_FULL_VERSION_STR, _TRUNCATE); + strncpy(output, ACE_FULL_VERSION_STR, outputSize); EXTENSION_RETURN(); } @@ -328,7 +328,7 @@ void __stdcall RVExtension(char *output, int outputSize, const char *function) // int n = sprintf(output, "%f", retard); outputStr << retard; - strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE); + strncpy(output, outputStr.str().c_str(), outputSize); EXTENSION_RETURN(); } else if (!strcmp(mode, "atmosphericCorrection")) { @@ -347,7 +347,7 @@ void __stdcall RVExtension(char *output, int outputSize, const char *function) ballisticCoefficient = calculateAtmosphericCorrection(ballisticCoefficient, temperature, pressure, humidity, atmosphereModel); //int n = sprintf(output, "%f", ballisticCoefficient); outputStr << ballisticCoefficient; - strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE); + strncpy(output, outputStr.str().c_str(), outputSize); EXTENSION_RETURN(); } else if (!strcmp(mode, "new")) { unsigned int index = 0; @@ -453,7 +453,7 @@ void __stdcall RVExtension(char *output, int outputSize, const char *function) bulletDatabase[index].randGenerator.seed(bulletDatabase[index].randSeed); } - strncpy_s(output, outputSize, "", _TRUNCATE); + strncpy(output, "", outputSize); EXTENSION_RETURN(); } else if (!strcmp(mode, "simulate")) { // simulate:0:[-0.109985,542.529,-3.98301]:[3751.57,5332.23,214.252]:[0.598153,2.38829,0]:28.6:0:0.481542:0:215.16 @@ -567,7 +567,7 @@ void __stdcall RVExtension(char *output, int outputSize, const char *function) ace::vector3 offset(distribution(bulletDatabase[index].randGenerator), distribution(bulletDatabase[index].randGenerator), distribution(bulletDatabase[index].randGenerator)); double coef = 1.0f - bulletDatabase[index].transonicStabilityCoef; - double trueSpeed = trueVelocity.magnitude(); + double trueSpeed = trueVelocity.magnitude(); trueVelocity += offset * coef; trueVelocity = trueVelocity.normalize() * trueSpeed; }; @@ -622,7 +622,7 @@ void __stdcall RVExtension(char *output, int outputSize, const char *function) bulletDatabase[index].bulletVelocityPreviousFrame = bulletVelocityCurrentFrame + velocityOffset; outputStr << "[" << velocityOffset.x() << "," << velocityOffset.y() << "," << velocityOffset.z() << "]"; - strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE); + strncpy(output, outputStr.str().c_str(), outputSize); EXTENSION_RETURN(); } else if (!strcmp(mode, "set")) { int height = 0; @@ -637,7 +637,7 @@ void __stdcall RVExtension(char *output, int outputSize, const char *function) map->gridBuildingNums.push_back(numObjects); map->gridSurfaceIsWater.push_back(surfaceIsWater); - strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE); + strncpy(output, outputStr.str().c_str(), outputSize); EXTENSION_RETURN(); } else if (!strcmp(mode, "init")) { int mapSize = 0; @@ -653,7 +653,7 @@ void __stdcall RVExtension(char *output, int outputSize, const char *function) map = &mapDatabase[worldName]; if (map->gridHeights.size() == gridCells) { outputStr << "Terrain already initialized"; - strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE); + strncpy(output, outputStr.str().c_str(), outputSize); EXTENSION_RETURN(); } @@ -666,7 +666,7 @@ void __stdcall RVExtension(char *output, int outputSize, const char *function) map->gridBuildingNums.reserve(gridCells); map->gridSurfaceIsWater.reserve(gridCells); - strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE); + strncpy(output, outputStr.str().c_str(), outputSize); EXTENSION_RETURN(); } else if (!strcmp(mode, "replicateVanillaZero")) { float zeroRange = strtof(strtok_s(NULL, ":", &next_token), NULL); @@ -676,7 +676,7 @@ void __stdcall RVExtension(char *output, int outputSize, const char *function) float zeroAngle = replicateVanillaZero(zeroRange, initSpeed, airFriction); outputStr << DEGREES(zeroAngle); - strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE); + strncpy(output, outputStr.str().c_str(), outputSize); EXTENSION_RETURN(); } else if (!strcmp(mode, "calcZero")) { double zeroRange = strtod(strtok_s(NULL, ":", &next_token), NULL); @@ -687,7 +687,7 @@ void __stdcall RVExtension(char *output, int outputSize, const char *function) double zeroAngle = calculateVanillaZero(zeroRange, initSpeed, airFriction, boreHeight); outputStr << DEGREES(zeroAngle); - strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE); + strncpy(output, outputStr.str().c_str(), outputSize); EXTENSION_RETURN(); } else if (!strcmp(mode, "calcZeroAB")) { double zeroRange = strtod(strtok_s(NULL, ":", &next_token), NULL); @@ -703,9 +703,9 @@ void __stdcall RVExtension(char *output, int outputSize, const char *function) double zeroAngle = calculateAdvancedZero(zeroRange, muzzleVelocity, boreHeight, temperature, pressure, humidity, ballisticCoefficient, dragModel, atmosphereModel); outputStr << DEGREES(zeroAngle); - strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE); + strncpy(output, outputStr.str().c_str(), outputSize); EXTENSION_RETURN(); } - strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE); + strncpy(output, outputStr.str().c_str(), outputSize); EXTENSION_RETURN(); } diff --git a/extensions/break_line/ace_break_line.cpp b/extensions/break_line/ace_break_line.cpp index c408ceab5c..1ac9b9009d 100644 --- a/extensions/break_line/ace_break_line.cpp +++ b/extensions/break_line/ace_break_line.cpp @@ -64,9 +64,9 @@ std::string addLineBreaks(const std::vector &words) { void __stdcall RVExtension(char *output, int outputSize, const char *function) { ZERO_OUTPUT(); if (!strcmp(function, "version")) { - strncpy_s(output, outputSize, ACE_FULL_VERSION_STR, _TRUNCATE); + strncpy(output, ACE_FULL_VERSION_STR, outputSize); } else { - strncpy_s(output, outputSize, addLineBreaks(splitString(function)).c_str(), _TRUNCATE); + strncpy(output, addLineBreaks(splitString(function)).c_str(), outputSize); } EXTENSION_RETURN(); } diff --git a/extensions/clipboard/ace_clipboard.cpp b/extensions/clipboard/ace_clipboard.cpp index 0b3d965ad5..9b5cf09d55 100644 --- a/extensions/clipboard/ace_clipboard.cpp +++ b/extensions/clipboard/ace_clipboard.cpp @@ -33,7 +33,7 @@ void __stdcall RVExtension(char *output, int outputSize, const char *function) { } if (!strcmp(function, "version")) { - strncpy_s(output, outputSize, ACE_FULL_VERSION_STR, _TRUNCATE); + std::strncpy(output, ACE_FULL_VERSION_STR, outputSize); EXTENSION_RETURN(); } @@ -53,7 +53,7 @@ void __stdcall RVExtension(char *output, int outputSize, const char *function) { result = "GlobalAlloc() failed, GetLastError=" + GetLastError(); EXTENSION_RETURN(); } - strncpy_s(pClipboardData, gClipboardData.length(), gClipboardData.c_str(), _TRUNCATE); + strncpy(pClipboardData, gClipboardData.c_str(), gClipboardData.length()); // if success, system owns the memory, if fail, free it from the heap if (SetClipboardData(CF_TEXT, pClipboardData) == NULL) { @@ -72,7 +72,7 @@ void __stdcall RVExtension(char *output, int outputSize, const char *function) { } if (result.length() > 1) { - strncpy_s(output, outputSize, result.c_str(), _TRUNCATE); + strncpy(output, result.c_str(), outputSize); } #endif diff --git a/extensions/common/shared.hpp b/extensions/common/shared.hpp index a3cf1d154f..c7c8c61403 100644 --- a/extensions/common/shared.hpp +++ b/extensions/common/shared.hpp @@ -20,6 +20,8 @@ #include "ace_version.hpp" #include #include //std::isspace +#include +#include #ifdef _DEBUG #define ZERO_OUTPUT() { memset(output, 0x00, outputSize); } @@ -73,7 +75,7 @@ namespace ace { struct exception { exception(const uint32_t code_, const std::string & text_) : code(code_), text(text_) {} - + exception & operator= (const exception& other) { code = other.code; text = other.text; return *this; } bool operator == (const exception &r) const { return ( code == r.code ); } @@ -83,11 +85,11 @@ namespace ace { } #ifndef _WIN32 -#define __stdcall +#define __stdcall #endif #if defined(_MSC_VER) - // Microsoft + // Microsoft #define EXPORT __declspec(dllexport) #define IMPORT __declspec(dllimport) #elif defined(_GCC) diff --git a/extensions/common/vector.hpp b/extensions/common/vector.hpp index 4830e18ba5..101ee0746d 100644 --- a/extensions/common/vector.hpp +++ b/extensions/common/vector.hpp @@ -25,12 +25,12 @@ namespace ace { template class vector3 { public: - constexpr vector3() : + vector3() : _x(0), _y(0), _z(0) { } - constexpr vector3(const T x_, const T y_, const T z_) noexcept : + vector3(const T x_, const T y_, const T z_) : _x(x_), _y(y_), _z(z_) { @@ -47,7 +47,7 @@ namespace ace { _z = buffer[2]; } - constexpr vector3& operator= (const vector3& other) noexcept { _x = other.x(); _y = other.y(); _z = other.z(); return *this; } + vector3& operator= (const vector3& other) { _x = other.x(); _y = other.y(); _z = other.z(); return *this; } /*#ifdef _WIN32 && _DIRECTX vector3 & operator= (const XMFLOAT3& Float3) { _x = Float3.x; _y = Float3.y; _z = Float3.z; return *this; } #endif @@ -56,38 +56,38 @@ namespace ace { vector3 & operator= (const btVector3& bt_vec) { _x = bt_vec.x(); _y = bt_vec.y(); _z = bt_vec.z(); return *this; } #endif */ - constexpr vector3 operator * (const T& val) const { return vector3(_x * val, _y * val, _z * val); } - constexpr vector3 operator / (const T& val) const { T invVal = T(1) / val; return vector3(_x * invVal, _y * invVal, _z * invVal); } - constexpr vector3 operator + (const vector3& v) const { return vector3(_x + v.x(), _y + v.y(), _z + v.z()); } - constexpr vector3 operator / (const vector3& v) const { return vector3(_x / v.x(), _y / v.y(), _z / v.z()); } - constexpr vector3 operator * (const vector3& v) const { return vector3(_x * v.x(), _y * v.y(), _z * v.z()); } - constexpr vector3 operator - (const vector3& v) const { return vector3(_x - v.x(), _y - v.y(), _z - v.z()); } - constexpr vector3 operator - () const { return vector3(-_x, -_y, -_z); } + vector3 operator * (const T& val) const { return vector3(_x * val, _y * val, _z * val); } + vector3 operator / (const T& val) const { T invVal = T(1) / val; return vector3(_x * invVal, _y * invVal, _z * invVal); } + vector3 operator + (const vector3& v) const { return vector3(_x + v.x(), _y + v.y(), _z + v.z()); } + vector3 operator / (const vector3& v) const { return vector3(_x / v.x(), _y / v.y(), _z / v.z()); } + vector3 operator * (const vector3& v) const { return vector3(_x * v.x(), _y * v.y(), _z * v.z()); } + vector3 operator - (const vector3& v) const { return vector3(_x - v.x(), _y - v.y(), _z - v.z()); } + vector3 operator - () const { return vector3(-_x, -_y, -_z); } - constexpr vector3& operator *=(const vector3& v) noexcept { _x *= v._x; _y *= v._y; _z *= v._z; return *this; } - constexpr vector3& operator *=(T mag) noexcept { _x *= mag; _y *= mag; _z *= mag; return *this; } - constexpr vector3& operator /=(const vector3& v) noexcept { _x /= v._x; _y /= v._y; _z /= v._z; return *this; } - constexpr vector3& operator /=(T mag) noexcept { _x /= mag; _y /= mag; _y /= mag; return *this; } - constexpr vector3& operator +=(const vector3& v) noexcept { _x += v._x; _y += v._y; _z += v._z; return *this; } - constexpr vector3& operator -=(const vector3& v) noexcept { _x -= v._x; _y -= v._y; _z -= v._z; return *this; } + vector3& operator *=(const vector3& v) { _x *= v._x; _y *= v._y; _z *= v._z; return *this; } + vector3& operator *=(T mag) { _x *= mag; _y *= mag; _z *= mag; return *this; } + vector3& operator /=(const vector3& v) { _x /= v._x; _y /= v._y; _z /= v._z; return *this; } + vector3& operator /=(T mag) { _x /= mag; _y /= mag; _y /= mag; return *this; } + vector3& operator +=(const vector3& v) { _x += v._x; _y += v._y; _z += v._z; return *this; } + vector3& operator -=(const vector3& v) { _x -= v._x; _y -= v._y; _z -= v._z; return *this; } - bool operator == (const vector3 &r) const noexcept { return (_x == r.x() && _y == r.y() && _z == r.z()); } + bool operator == (const vector3 &r) const { return (_x == r.x() && _y == r.y() && _z == r.z()); } - constexpr T magnitude() const noexcept { return sqrt(_x * _x + _y * _y + _z * _z); } - constexpr T magnitude_squared() const noexcept { return _x * _x + _y * _y + _z * _z; } - constexpr T dot(const vector3& v) const noexcept { return (_x * v.x() + _y * v.y() + _z * v.z()); } - constexpr T distance(const vector3& v) const noexcept { vector3 dist = (*this - v); dist = dist * dist; return sqrt(dist.x() + dist.y() + dist.z()); } - constexpr vector3 cross(const vector3& v) const noexcept { return vector3(_y * v.z() - _z * v.y(), _z * v.x() - _x * v.z(), _x * v.y() - _y * v.x()); } - constexpr vector3 normalize() const noexcept { return (*this / abs(magnitude())); }; - constexpr bool zero_distance() const noexcept { return ((_x == 0.0f && _y == 0.0f && _z == 0.0f) ? true : false ); } + T magnitude() const { return sqrt(_x * _x + _y * _y + _z * _z); } + T magnitude_squared() const { return _x * _x + _y * _y + _z * _z; } + T dot(const vector3& v) const { return (_x * v.x() + _y * v.y() + _z * v.z()); } + T distance(const vector3& v) const { vector3 dist = (*this - v); dist = dist * dist; return sqrt(dist.x() + dist.y() + dist.z()); } + vector3 cross(const vector3& v) const { return vector3(_y * v.z() - _z * v.y(), _z * v.x() - _x * v.z(), _x * v.y() - _y * v.x()); } + vector3 normalize() const { return (*this / abs(magnitude())); }; + bool zero_distance() const { return ((_x == 0.0f && _y == 0.0f && _z == 0.0f) ? true : false ); } static float clamp(T x, T a, T b) { return x < a ? a : (x > b ? b : x); } - static vector3 lerp(const vector3& A, const vector3& B, const T t) noexcept { return A*t + B*(1.f - t); } - constexpr vector3 lerp(const vector3& B, const T t) const noexcept { return vector3::lerp(*this, B, t); } + static vector3 lerp(const vector3& A, const vector3& B, const T t) { return A*t + B*(1.f - t); } + vector3 lerp(const vector3& B, const T t) const { return vector3::lerp(*this, B, t); } - static vector3 slerp(vector3 start, vector3 end, T percent) noexcept { + static vector3 slerp(vector3 start, vector3 end, T percent) { T dot = start.dot(end); dot = vector3::clamp(dot, -1.0f, 1.0f); @@ -96,13 +96,13 @@ namespace ace { relative.normalize(); return ((start * cos(theta)) + (relative*sin(theta))); } - constexpr vector3 slerp(const vector3& B, const T p) const noexcept { + vector3 slerp(const vector3& B, const T p) const { return vector3::slerp(*this, B, p); } - const T& x() const noexcept { return _x; } - const T& y() const noexcept { return _y; } - const T& z() const noexcept { return _z; } + const T& x() const { return _x; } + const T& y() const { return _y; } + const T& z() const { return _z; } void x(const T val) { _x = val; } void y(const T val) { _y = val; } diff --git a/extensions/fcs/ace_fcs.cpp b/extensions/fcs/ace_fcs.cpp index 8ab57a1c77..1c00212c27 100644 --- a/extensions/fcs/ace_fcs.cpp +++ b/extensions/fcs/ace_fcs.cpp @@ -96,7 +96,7 @@ double getSolution(double initSpeed, double airFriction, double angleTarget, dou void __stdcall RVExtension(char *output, int outputSize, const char *function) { ZERO_OUTPUT(); if (!strcmp(function, "version")) { - strncpy_s(output, outputSize, ACE_FULL_VERSION_STR, _TRUNCATE); + strncpy(output, ACE_FULL_VERSION_STR, outputSize); } else { std::vector argStrings = splitString(function); double initSpeed = std::stod(argStrings[0]); @@ -109,7 +109,7 @@ void __stdcall RVExtension(char *output, int outputSize, const char *function) { std::stringstream sstream; sstream << result; - strncpy_s(output, outputSize, sstream.str().c_str(), _TRUNCATE); + strncpy(output, sstream.str().c_str(), outputSize); } EXTENSION_RETURN(); } diff --git a/extensions/medical/handleDamage.cpp b/extensions/medical/handleDamage.cpp index 001877a2cd..9b0e5e78ef 100644 --- a/extensions/medical/handleDamage.cpp +++ b/extensions/medical/handleDamage.cpp @@ -34,7 +34,7 @@ namespace ace { double painToAdd = 0; wounds = GetInjuryInfoFor(typeOfDamage, amountOfDamage, selectionN, woundID); - stream << "_woundsCreated = ["; + stream << "[["; for (int i = 0; i < wounds.size(); ++i) { stream << wounds.at(i).AsString(); @@ -45,9 +45,9 @@ namespace ace { painToAdd += wounds.at(i).pain; } - stream << "];"; + stream << "],"; - stream << "_painToAdd = " << painToAdd << ";"; + stream << painToAdd << "]"; return stream.str(); } diff --git a/extensions/medical/medical.cpp b/extensions/medical/medical.cpp index aca062e205..ef6c00fde9 100644 --- a/extensions/medical/medical.cpp +++ b/extensions/medical/medical.cpp @@ -33,7 +33,7 @@ std::vector parseExtensionInput(const std::string& input) void __stdcall RVExtension(char *output, int outputSize, const char *function) { if (!strcmp(function, "version")) { - strncpy_s(output, outputSize, ACE_FULL_VERSION_STR, _TRUNCATE); + strncpy(output, ACE_FULL_VERSION_STR, outputSize); } else { @@ -85,6 +85,6 @@ void __stdcall RVExtension(char *output, int outputSize, const char *function) { } } - strncpy_s(output, outputSize, returnValue.c_str(), _TRUNCATE); + strncpy(output, returnValue.c_str(), outputSize); } } diff --git a/extensions/parse_imagepath/ace_parse_imagepath.cpp b/extensions/parse_imagepath/ace_parse_imagepath.cpp index 110cb904cc..8f52a1e4bc 100644 --- a/extensions/parse_imagepath/ace_parse_imagepath.cpp +++ b/extensions/parse_imagepath/ace_parse_imagepath.cpp @@ -40,9 +40,9 @@ std::string getImagePathFromStructuredText(const std::string & input) { void __stdcall RVExtension(char *output, int outputSize, const char *function) { ZERO_OUTPUT(); if (!strcmp(function, "version")) { - strncpy_s(output, outputSize, ACE_FULL_VERSION_STR, _TRUNCATE); + strncpy(output, ACE_FULL_VERSION_STR, outputSize); } else { - strncpy_s(output, outputSize, getImagePathFromStructuredText(function).c_str(), _TRUNCATE); + strncpy(output, getImagePathFromStructuredText(function).c_str(), outputSize); } EXTENSION_RETURN(); } diff --git a/include/x/cba/addons/main/script_macros_common.hpp b/include/x/cba/addons/main/script_macros_common.hpp index 4efb3c7128..41a4faea75 100644 --- a/include/x/cba/addons/main/script_macros_common.hpp +++ b/include/x/cba/addons/main/script_macros_common.hpp @@ -51,21 +51,55 @@ #define MAINLOGIC main #endif +#define ADDON DOUBLES(PREFIX,COMPONENT) +#define MAIN_ADDON DOUBLES(PREFIX,main) + +/* ------------------------------------------- +Macro: VERSION_CONFIG + Define CBA Versioning System config entries. + + VERSION should be a floating-point number (1 separator). + VERSION_STR is a string representation of the version. + VERSION_AR is an array representation of the version. + + VERSION must always be defined, otherwise it is 0. + VERSION_STR and VERSION_AR default to VERSION if undefined. + +Parameters: + None + +Example: + (begin example) + #define VERSION 1.0 + #define VERSION_STR 1.0.1 + #define VERSION_AR 1,0,1 + + class CfgPatches { + class MyMod_main { + VERSION_CONFIG; + }; + }; + (end) + +Author: + ?, Jonpas +------------------------------------------- */ #ifndef VERSION #define VERSION 0 #endif +#ifndef VERSION_STR + #define VERSION_STR VERSION +#endif + #ifndef VERSION_AR #define VERSION_AR VERSION #endif #ifndef VERSION_CONFIG - #define VERSION_CONFIG version = VERSION; versionStr = QUOTE(VERSION); versionAr[] = {VERSION_AR} + #define VERSION_CONFIG version = VERSION; versionStr = QUOTE(VERSION_STR); versionAr[] = {VERSION_AR} #endif -#define ADDON DOUBLES(PREFIX,COMPONENT) -#define MAIN_ADDON DOUBLES(PREFIX,main) - /* ------------------------------------------- Group: Debugging ------------------------------------------- */ @@ -775,7 +809,7 @@ Author: // This only works for binarized configs after recompiling the pbos // TODO: Reduce amount of calls / code.. -#define COMPILE_FILE2_CFG_SYS(var1) compile preProcessFileLineNumbers var1 +#define COMPILE_FILE2_CFG_SYS(var1) compile preprocessFileLineNumbers var1 #define COMPILE_FILE2_SYS(var1) COMPILE_FILE2_CFG_SYS(var1) #define COMPILE_FILE_SYS(var1,var2,var3) COMPILE_FILE2_SYS('PATHTO_SYS(var1,var2,var3)') @@ -785,13 +819,13 @@ Author: #define SETVARMAINS(var1) SETVARS(var1,MAINLOGIC) #define GVARMAINS(var1,var2) var1##_##var2 #define CFGSETTINGSS(var1,var2) configFile >> "CfgSettings" >> #var1 >> #var2 -//#define SETGVARS(var1,var2,var3) ##var1##_##var2##_##var3 = -//#define SETGVARMAINS(var1,var2) ##var1##_##var2 = +//#define SETGVARS(var1,var2,var3) var1##_##var2##_##var3 = +//#define SETGVARMAINS(var1,var2) var1##_##var2 = // Compile-Once, JIT: On first use. -// #define PREPMAIN_SYS(var1,var2,var3) ##var1##_fnc_##var3 = { ##var1##_fnc_##var3 = COMPILE_FILE_SYS(var1,var2,DOUBLES(fnc,var3)); if (isNil "_this") then { call ##var1##_fnc_##var3 } else { _this call ##var1##_fnc_##var3 } } -// #define PREP_SYS(var1,var2,var3) ##var1##_##var2##_fnc_##var3 = { ##var1##_##var2##_fnc_##var3 = COMPILE_FILE_SYS(var1,var2,DOUBLES(fnc,var3)); if (isNil "_this") then { call ##var1##_##var2##_fnc_##var3 } else { _this call ##var1##_##var2##_fnc_##var3 } } -// #define PREP_SYS2(var1,var2,var3,var4) ##var1##_##var2##_fnc_##var4 = { ##var1##_##var2##_fnc_##var4 = COMPILE_FILE_SYS(var1,var3,DOUBLES(fnc,var4)); if (isNil "_this") then { call ##var1##_##var2##_fnc_##var4 } else { _this call ##var1##_##var2##_fnc_##var4 } } +// #define PREPMAIN_SYS(var1,var2,var3) var1##_fnc_##var3 = { var1##_fnc_##var3 = COMPILE_FILE_SYS(var1,var2,DOUBLES(fnc,var3)); if (isNil "_this") then { call var1##_fnc_##var3 } else { _this call var1##_fnc_##var3 } } +// #define PREP_SYS(var1,var2,var3) var1##_##var2##_fnc_##var3 = { var1##_##var2##_fnc_##var3 = COMPILE_FILE_SYS(var1,var2,DOUBLES(fnc,var3)); if (isNil "_this") then { call var1##_##var2##_fnc_##var3 } else { _this call var1##_##var2##_fnc_##var3 } } +// #define PREP_SYS2(var1,var2,var3,var4) var1##_##var2##_fnc_##var4 = { var1##_##var2##_fnc_##var4 = COMPILE_FILE_SYS(var1,var3,DOUBLES(fnc,var4)); if (isNil "_this") then { call var1##_##var2##_fnc_##var4 } else { _this call var1##_##var2##_fnc_##var4 } } // Compile-Once, at Macro. As opposed to Compile-Once, on first use. #define PREPMAIN_SYS(var1,var2,var3) var1##_fnc_##var3 = COMPILE_FILE_SYS(var1,var2,DOUBLES(fnc,var3)) @@ -890,6 +924,39 @@ Author: #define SETVARMAIN SETVARMAINS(PREFIX) #define IFCOUNT(var1,var2,var3) if (count var1 > var2) then { var3 = var1 select var2 }; +/* ------------------------------------------- +Macro: PREP() + +Description: + Defines a function. + + Full file path: + '\MAINPREFIX\PREFIX\SUBPREFIX\COMPONENT\fnc_.sqf' + + Resulting function name: + 'PREFIX_COMPONENT_' + + The PREP macro should be placed in a script run by a XEH preStart and XEH preInit event. + + The PREP macro allows for CBA function caching, which drastically speeds up load times. + Beware though that function caching is enabled by default and as such to disable it, you need to + #define DISABLE_COMPILE_CACHE above your #include "script_components.hpp" include! + + The function will be defined in ui and mission namespace. It can not be overwritten without + a mission restart. + +Parameters: + FUNCTION NAME - Name of the function, unquoted + +Examples: + (begin example) + PREP(banana); + call FUNC(banana); + (end) + +Author: + dixon13 + ------------------------------------------- */ //#define PREP(var1) PREP_SYS(PREFIX,COMPONENT_F,var1) #ifdef DISABLE_COMPILE_CACHE @@ -900,13 +967,6 @@ Author: #define PREPMAIN(var1) ['PATHTO_SYS(PREFIX,COMPONENT_F,DOUBLES(fnc,var1))', 'TRIPLES(PREFIX,fnc,var1)'] call SLX_XEH_COMPILE_NEW #endif -#ifdef RECOMPILE - #undef RECOMPILE - #define RECOMPILE recompile = 1 -#else - #define RECOMPILE recompile = 0 -#endif - /* ------------------------------------------- Macro: PATHTO_FNC() @@ -916,6 +976,7 @@ Description: Full file path in addons: '\MAINPREFIX\PREFIX\SUBPREFIX\COMPONENT\fnc_.sqf' Define 'RECOMPILE' to enable recompiling. + Define 'SKIP_FUNCTION_HEADER' to skip adding function header. Parameters: FUNCTION NAME - Name of the function, unquoted @@ -936,8 +997,22 @@ Examples: Author: dixon13, commy2 ------------------------------------------- */ +#ifdef RECOMPILE + #undef RECOMPILE + #define RECOMPILE recompile = 1 +#else + #define RECOMPILE recompile = 0 +#endif +// Set function header type: -1 - no header; 0 - default header; 1 - system header. +#ifdef SKIP_FUNCTION_HEADER + #define CFGFUNCTION_HEADER headerType = -1 +#else + #define CFGFUNCTION_HEADER headerType = 0 +#endif + #define PATHTO_FNC(func) class func {\ file = QPATHTOF(DOUBLES(fnc,func).sqf);\ + CFGFUNCTION_HEADER;\ RECOMPILE;\ } @@ -1086,6 +1161,7 @@ Author: /* ------------------------------------------- Macro: SCRIPT() Sets name of script (relies on PREFIX and COMPONENT values being #defined). + Define 'SKIP_SCRIPT_NAME' to skip adding scriptName. Parameters: NAME - Name of script [Indentifier] @@ -1098,8 +1174,11 @@ Example: Author: Spooner ------------------------------------------- */ -#define SCRIPT(NAME) \ - scriptName 'PREFIX\COMPONENT\NAME' +#ifndef SKIP_SCRIPT_NAME + #define SCRIPT(NAME) scriptName 'PREFIX\COMPONENT\NAME' +#else + #define SCRIPT(NAME) /* nope */ +#endif /* ------------------------------------------- Macros: EXPLODE_n() diff --git a/optionals/compat_rhs_afrf3/CfgAmmo.hpp b/optionals/compat_rhs_afrf3/CfgAmmo.hpp index deebfe92ef..1af1a2bcab 100644 --- a/optionals/compat_rhs_afrf3/CfgAmmo.hpp +++ b/optionals/compat_rhs_afrf3/CfgAmmo.hpp @@ -153,25 +153,11 @@ class CfgAmmo { ace_frag_skip = 0; ace_frag_force = 1; }; - class rhs_ammo_rgn_base: rhs_ammo_rgd5 { - ace_frag_enabled = 1; - ace_frag_metal = 193; - ace_frag_charge = 97; - ace_frag_gurney_c = 2800; - ace_frag_gurney_k = "3/5"; - ace_frag_classes[] = {"ACE_frag_tiny_HD"}; - ace_frag_skip = 0; - ace_frag_force = 1; - }; - class rhs_ammo_rgn: rhs_ammo_rgn_base { - // RGN is scripted grenade that deletes itself, which will break advanced throwing, replace with it's base - ace_advanced_throwing_replaceWith = "rhs_ammo_rgn_base"; + class rhs_ammo_rgn: rhs_ammo_rgd5 { ace_frag_enabled = 0; ace_frag_skip = 1; ace_frag_force = 0; }; - class rhs_ammo_rgn_sub: rhs_ammo_rgn_base {}; - class rhs_ammo_rgn_exp: rhs_ammo_rgn_base {}; class rhs_ammo_fakel: GrenadeHand { ace_frag_enabled = 0; ace_frag_skip = 1; @@ -205,7 +191,7 @@ class CfgAmmo { ace_frag_skip = 1; ace_frag_force = 0; }; - + class G_40mm_HE; class rhs_g_vog25: G_40mm_HE {}; class rhs_g_vg40tb: rhs_g_vog25 { //Thermobaric @@ -220,5 +206,5 @@ class CfgAmmo { class rhs_g_vg40md_white: rhs_g_vog25 { //Smoke ace_frag_force = 0; }; - + }; diff --git a/optionals/compat_rhs_afrf3/CfgMagazineGroups.hpp b/optionals/compat_rhs_afrf3/CfgMagazineGroups.hpp new file mode 100644 index 0000000000..4eb8f84779 --- /dev/null +++ b/optionals/compat_rhs_afrf3/CfgMagazineGroups.hpp @@ -0,0 +1,18 @@ +#define CREATE_MAGAZINE_GROUP(ammo) class GVAR(ammo) { rhs_##ammo = 1; } +class ace_csw_groups { + CREATE_MAGAZINE_GROUP(mag_9M131M); + CREATE_MAGAZINE_GROUP(mag_9M131F); + CREATE_MAGAZINE_GROUP(mag_9m133); + CREATE_MAGAZINE_GROUP(mag_9m133f); + CREATE_MAGAZINE_GROUP(mag_9m1331); + CREATE_MAGAZINE_GROUP(mag_9m133m2); + CREATE_MAGAZINE_GROUP(mag_PG9V); + CREATE_MAGAZINE_GROUP(mag_PG9N); + CREATE_MAGAZINE_GROUP(mag_PG9VNT); + CREATE_MAGAZINE_GROUP(mag_OG9VM); + CREATE_MAGAZINE_GROUP(mag_OG9V); + CREATE_MAGAZINE_GROUP(mag_VOG30_30); + CREATE_MAGAZINE_GROUP(mag_GPD30_30); + CREATE_MAGAZINE_GROUP(mag_VOG17m_30); +}; + diff --git a/optionals/compat_rhs_afrf3/CfgMagazines.hpp b/optionals/compat_rhs_afrf3/CfgMagazines.hpp index 1ce1a43b04..81a942f526 100644 --- a/optionals/compat_rhs_afrf3/CfgMagazines.hpp +++ b/optionals/compat_rhs_afrf3/CfgMagazines.hpp @@ -14,4 +14,136 @@ class cfgMagazines { class rhs_mag_127x108mm_1470 : rhs_mag_127x108mm_50 { ace_isbelt = 0; }; + class RHS_mag_VOG30_30: VehicleMagazine { + ace_isbelt = 1; + }; + class RHS_mag_GPD30_30: RHS_mag_VOG30_30 {}; + + // RHS magazines for crew handled ammo + class rhs_mag_9M131M; + class GVAR(mag_9M131M): rhs_mag_9M131M { + scope = 2; + type = 256; + count = 1; + mass = 55; + model = "rhsafrf\addons\rhs_heavyweapons\atgm\rhs_metis_emptytube.p3d"; + picture = "\A3\Weapons_F_Tank\Launchers\Vorona\Data\UI\icon_rocket_vorona_HEAT_F_ca.paa"; + }; + class rhs_mag_9M131F; + class GVAR(mag_9M131F): rhs_mag_9M131F { + scope = 2; + type = 256; + count = 1; + mass = 55; + model = "rhsafrf\addons\rhs_heavyweapons\atgm\rhs_metis_emptytube.p3d"; + picture = "\A3\Weapons_F_Tank\Launchers\Vorona\Data\UI\icon_rocket_vorona_HEAT_F_ca.paa"; + }; + class rhs_mag_9m133; + class GVAR(mag_9m133): rhs_mag_9m133 { + scope = 2; + type = 256; + count = 1; + mass = 55; + model = "rhsafrf\addons\rhs_heavyweapons\atgm\rhs_kornet_emptytube.p3d"; + picture = "\A3\Weapons_F_Tank\Launchers\Vorona\Data\UI\icon_rocket_vorona_HEAT_F_ca.paa"; + }; + class rhs_mag_9m133f; + class GVAR(mag_9m133f): rhs_mag_9m133f { + scope = 2; + type = 256; + count = 1; + mass = 55; + model = "rhsafrf\addons\rhs_heavyweapons\atgm\rhs_kornet_emptytube.p3d"; + picture = "\A3\Weapons_F_Tank\Launchers\Vorona\Data\UI\icon_rocket_vorona_HEAT_F_ca.paa"; + }; + class rhs_mag_9m1331; + class GVAR(mag_9m1331): rhs_mag_9m1331 { + scope = 2; + type = 256; + count = 1; + mass = 55; + model = "rhsafrf\addons\rhs_heavyweapons\atgm\rhs_kornet_emptytube.p3d"; + picture = "\A3\Weapons_F_Tank\Launchers\Vorona\Data\UI\icon_rocket_vorona_HEAT_F_ca.paa"; + }; + class rhs_mag_9m133m2; + class GVAR(mag_9m133m2): rhs_mag_9m133m2 { + scope = 2; + type = 256; + count = 1; + mass = 55; + model = "rhsafrf\addons\rhs_heavyweapons\atgm\rhs_kornet_emptytube.p3d"; + picture = "\A3\Weapons_F_Tank\Launchers\Vorona\Data\UI\icon_rocket_vorona_HEAT_F_ca.paa"; + }; + class rhs_mag_PG9V; + class GVAR(mag_PG9V): rhs_mag_PG9V { + scope = 2; + type = 256; + count = 1; + mass = 80; + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; + picture = "\A3\Weapons_F_Exp\Launchers\RPG7\Data\UI\icon_rocket_RPG7_CA.paa"; + }; + class rhs_mag_PG9N; + class GVAR(mag_PG9N): rhs_mag_PG9N { + scope = 2; + type = 256; + count = 1; + mass = 80; + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; + picture = "\A3\Weapons_F_Exp\Launchers\RPG7\Data\UI\icon_rocket_RPG7_CA.paa"; + }; + class rhs_mag_PG9VNT; + class GVAR(mag_PG9VNT): rhs_mag_PG9VNT { + scope = 2; + type = 256; + count = 1; + mass = 80; + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; + picture = "\A3\Weapons_F_Exp\Launchers\RPG7\Data\UI\icon_rocket_RPG7_CA.paa"; + }; + class rhs_mag_OG9VM; + class GVAR(mag_OG9VM): rhs_mag_OG9VM { + scope = 2; + type = 256; + count = 1; + mass = 80; + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; + picture = "\A3\Weapons_F_Exp\Launchers\RPG7\Data\UI\icon_rocket_RPG7_CA.paa"; + }; + class rhs_mag_OG9V; + class GVAR(mag_OG9V): rhs_mag_OG9V { + scope = 2; + type = 256; + count = 1; + mass = 80; + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; + picture = "\A3\Weapons_F_Exp\Launchers\RPG7\Data\UI\icon_rocket_RPG7_CA.paa"; + }; + + class GVAR(mag_VOG30_30): RHS_mag_VOG30_30 { + scope = 2; + type = 256; + count = 30; + mass = 40; + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; + picture = QPATHTOEF(csw,UI\ammoBox_50bmg_ca.paa); + }; + class GVAR(mag_GPD30_30): RHS_mag_GPD30_30 { + scope = 2; + type = 256; + count = 30; + mass = 40; + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; + picture = QPATHTOEF(csw,UI\ammoBox_50bmg_ca.paa); + }; + class RHS_mag_VOG17m_30; + class GVAR(mag_VOG17m_30): RHS_mag_VOG17m_30 { + scope = 2; + type = 256; + count = 30; + mass = 40; + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; + picture = QPATHTOEF(csw,UI\ammoBox_50bmg_ca.paa); + }; + }; diff --git a/optionals/compat_rhs_afrf3/CfgVehicles.hpp b/optionals/compat_rhs_afrf3/CfgVehicles.hpp index 068f22280c..b614807536 100644 --- a/optionals/compat_rhs_afrf3/CfgVehicles.hpp +++ b/optionals/compat_rhs_afrf3/CfgVehicles.hpp @@ -233,6 +233,17 @@ class CfgVehicles { position = ""; }; }; + // ENABLE_CSW_ATTRIBUTE; + class ACE_CSW { + enabled = 1; + proxyWeapon = QGVAR(rhs_weap_SPG9); + magazineLocation = "_target selectionPosition 'breach'"; + disassembleWeapon = QGVAR(spg9_carry); + disassembleTurret = QEGVAR(csw,spg9Tripod); + desiredAmmo = 1; + ammoLoadTime = 5; + ammoUnloadTime = 3; + }; }; class rhs_Kornet_Base: AT_01_base_F { class ACE_Actions: ACE_Actions { @@ -241,10 +252,109 @@ class CfgVehicles { selection = "tripod"; }; }; + // ENABLE_CSW_ATTRIBUTE; + class ACE_CSW { + enabled = 1; + proxyWeapon = QGVAR(rhs_weap_9K133_launcher); + magazineLocation = "_target selectionPosition 'gun'"; + disassembleWeapon = QGVAR(kornet_carry); + disassembleTurret = ""; + desiredAmmo = 1; + ammoLoadTime = 7; + ammoUnloadTime = 5; + }; }; class rhs_assault_umbts; class rhs_assault_umbts_engineer: rhs_assault_umbts { EGVAR(logistics_wirecutter,hasWirecutter) = 1; }; + + class StaticMortar: StaticWeapon {}; + class rhs_2b14_82mm_Base: StaticMortar { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = ""; + selection = ""; // no good selections for this mortar + }; + }; + // ENABLE_CSW_ATTRIBUTE; + class ACE_CSW { + enabled = 1; + magazineLocation = ""; + proxyWeapon = QGVAR(rhs_weap_2b14); + disassembleWeapon = QGVAR(2b14_carry); // carry weapon [CfgWeapons] + disassembleTurret = QEGVAR(csw,mortarBaseplate); // turret [CfgVehicles] + desiredAmmo = 1; + ammoLoadTime = 3; + ammoUnloadTime = 3; + }; + }; + + class rhs_nsv_tripod_base: StaticMGWeapon { + class ACE_CSW { + enabled = 1; + proxyWeapon = QGVAR(rhs_weap_nsvt_effects); + magazineLocation = "_target selectionPosition 'magazine'"; + disassembleWeapon = QGVAR(nsv_carry); + disassembleTurret = QEGVAR(csw,kordTripodLow); + desiredAmmo = 50; + ammoLoadTime = 10; + ammoUnloadTime = 8; + }; + }; + + class RHS_KORD_Base: rhs_nsv_tripod_base { + class ACE_CSW: ACE_CSW { + enabled = 1; + proxyWeapon = QGVAR(rhs_weap_KORD); + disassembleWeapon = QGVAR(kord_carry); + disassembleTurret = QEGVAR(csw,kordTripodLow); + }; + }; + + class RHS_KORD_high_base: RHS_KORD_Base { + class ACE_CSW: ACE_CSW { + enabled = 1; + proxyWeapon = QGVAR(rhs_weap_KORD); + disassembleWeapon = QGVAR(kord_carry); + disassembleTurret = QEGVAR(csw,kordTripod); + }; + }; + + class StaticGrenadeLauncher: StaticWeapon {}; + class RHS_AGS30_TriPod_base: StaticGrenadeLauncher { + // ENABLE_CSW_ATTRIBUTE; + class ACE_CSW { + enabled = 1; + proxyWeapon = QGVAR(rhs_weap_AGS30); + magazineLocation = "_target selectionPosition 'magazine'"; + disassembleWeapon = QGVAR(ags30_carry); + disassembleTurret = QEGVAR(csw,sag30Tripod); + desiredAmmo = 30; + ammoLoadTime = 10; + ammoUnloadTime = 8; + }; + }; + + class rhs_SPG9M_base: rhs_SPG9_base { + class ACE_CSW: ACE_CSW { + enabled = 1; + disassembleWeapon = QGVAR(spg9m_carry); + }; + }; + + class rhs_Metis_Base: AT_01_base_F { + // ENABLE_CSW_ATTRIBUTE; + class ACE_CSW { + enabled = 1; + proxyWeapon = QGVAR(rhs_weap_9K115_2_launcher); + magazineLocation = "_target selectionPosition 'gun'"; + disassembleWeapon = QGVAR(metis_carry); + disassembleTurret = ""; + desiredAmmo = 1; + ammoLoadTime = 7; + ammoUnloadTime = 5; + }; + }; }; diff --git a/optionals/compat_rhs_afrf3/CfgWeapons.hpp b/optionals/compat_rhs_afrf3/CfgWeapons.hpp index f09d1cc787..d9cbece55c 100644 --- a/optionals/compat_rhs_afrf3/CfgWeapons.hpp +++ b/optionals/compat_rhs_afrf3/CfgWeapons.hpp @@ -1,13 +1,12 @@ - class CfgWeapons { - + class NVGoggles; class rhs_1PN138: NVGoggles { // Monocular modelOptics = ""; EGVAR(nightvision,border) = QPATHTOEF(nightvision,data\nvg_mask_4096.paa); EGVAR(nightvision,bluRadius) = 0.13; }; - + class hgun_Rook40_F; class rhs_weap_pya: hgun_Rook40_F { ACE_barrelTwist = 254.0; @@ -86,7 +85,7 @@ class CfgWeapons { ACE_ScopeAdjust_VerticalIncrement = 0.5; ACE_ScopeAdjust_HorizontalIncrement = 0.5; }; - class rhs_acc_pso1m21: rhs_acc_sniper_base { + class rhs_acc_pso1m21: rhs_acc_pso1m2 { ACE_ScopeHeightAboveRail = 7.75566; ACE_ScopeAdjust_Vertical[] = {0, 0}; ACE_ScopeAdjust_Horizontal[] = {-10, 10}; @@ -110,7 +109,10 @@ class CfgWeapons { }; }; }; - class Launcher_Base_F; + class Launcher; + class Launcher_Base_F: Launcher { + class WeaponSlotsInfo; + }; class rhs_weap_rpg7: Launcher_Base_F { ace_reloadlaunchers_enabled = 1; }; @@ -141,4 +143,157 @@ class CfgWeapons { ace_overpressure_range = 15; ace_overpressure_damage = 0.5; }; + + CREATE_CSW_PROXY(rhs_weap_2b14); + CREATE_CSW_PROXY(rhs_weap_nsvt_effects); + CREATE_CSW_PROXY(rhs_weap_KORD); + CREATE_CSW_PROXY(RHS_weap_AGS30); + CREATE_CSW_PROXY(rhs_weap_SPG9); + CREATE_CSW_PROXY(rhs_weap_9K133_launcher); + CREATE_CSW_PROXY(rhs_weap_9K115_2_launcher); + + class GVAR(2b14_carry): Launcher_Base_F { + class ACE_CSW { + type = "weapon"; + deployTime = 20; + pickupTime = 25; + class assembleTo { + EGVAR(csw,mortarBaseplate) = "rhs_2b14_82mm_msv"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 670; // 2B14 Mortar Weight + }; + displayName = ECSTRING(CSW,2b14_tube); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = "\rhsafrf\addons\rhs_heavyweapons\data\ico\rhs_2b14_82mm_msv_ca.paa"; + }; + + class GVAR(nsv_carry): Launcher_Base_F { + class ACE_CSW { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + EGVAR(csw,kordTripodLow) = "RHS_NSV_TriPod_MSV"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 550; + }; + displayName = ECSTRING(CSW,nsv_gun); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = "\rhsafrf\addons\rhs_heavyweapons\data\ico\RHS_NSV_TriPod_MSV_ca.paa"; + }; + + class GVAR(kord_carry): Launcher_Base_F { + class ACE_CSW { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + EGVAR(csw,kordTripod) = "rhs_KORD_high_MSV"; + EGVAR(csw,kordTripodLow) = "rhs_KORD_MSV"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 550; + }; + displayName = ECSTRING(CSW,kord_gun); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = "\rhsafrf\addons\rhs_heavyweapons\data\ico\rhs_KORD_MSV_ca.paa"; + }; + + class GVAR(ags30_carry): Launcher_Base_F { + class ACE_CSW { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + EGVAR(csw,sag30Tripod) = "RHS_AGS30_TriPod_MSV"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 400; // https://odin.tradoc.army.mil/mediawiki/index.php/AGS-17_Russian_30mm_Automatic_Grenade_Launcher + }; + displayName = ECSTRING(CSW,ags30_gun); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = "\rhsafrf\addons\rhs_heavyweapons\data\ico\RHS_AGS30_TriPod_MSV_ca.paa"; + }; + + class GVAR(spg9_carry): Launcher_Base_F { + class ACE_CSW { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + EGVAR(csw,spg9Tripod) = "rhsgref_ins_SPG9"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 1000; + }; + displayName = ECSTRING(csw,spg9_tube); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = "\rhsafrf\addons\rhs_heavyweapons\data\ico\rhs_SPG9_INS_ca.paa"; + }; + class GVAR(spg9m_carry): GVAR(spg9_carry) { + class ACE_CSW { + class assembleTo { + EGVAR(csw,spg9Tripod) = "rhs_SPG9M_MSV"; + }; + }; + displayName = ECSTRING(csw,spg9m_tube); + }; + + class GVAR(metis_carry): Launcher_Base_F { + class ACE_CSW { + type = "mount"; + deployTime = 4; + pickupTime = 4; + deploy = "rhs_Metis_9k115_2_msv"; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 300; + }; + displayName = ECSTRING(csw,metis_tube); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = "\rhsafrf\addons\rhs_heavyweapons\data\ico\rhs_Metis_9k115_2_msv_ca.paa"; + }; + + class GVAR(kornet_carry): Launcher_Base_F { + class ACE_CSW { + type = "mount"; + deployTime = 4; + pickupTime = 4; + deploy = "rhs_Kornet_9M133_2_msv"; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 600; + }; + displayName = ECSTRING(csw,kornet_launcher); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = "\rhsafrf\addons\rhs_heavyweapons\data\ico\rhs_Kornet_9M133_2_msv_ca.paa"; + }; }; diff --git a/optionals/compat_rhs_afrf3/config.cpp b/optionals/compat_rhs_afrf3/config.cpp index b7cfe3f233..1e253eb125 100644 --- a/optionals/compat_rhs_afrf3/config.cpp +++ b/optionals/compat_rhs_afrf3/config.cpp @@ -1,4 +1,5 @@ #include "script_component.hpp" +#include "\z\ace\addons\csw\script_config_macros_csw.hpp" class CfgPatches { class ADDON { @@ -6,7 +7,7 @@ class CfgPatches { units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"ace_rearm", "ace_refuel", "ace_repair", "rhs_c_weapons", "rhs_c_troops", "rhs_c_bmd", "rhs_c_bmp", "rhs_c_bmp3", "rhs_c_a2port_armor", "rhs_c_btr", "rhs_c_sprut", "rhs_c_t72", "rhs_c_tanks", "rhs_c_a2port_air", "rhs_c_a2port_car", "rhs_c_cars", "rhs_c_trucks", "rhs_c_2s3", "rhs_c_rva", "rhs_c_heavyweapons"}; + requiredAddons[] = {"ace_csw", "ace_rearm", "ace_refuel", "ace_repair", "rhs_c_weapons", "rhs_c_troops", "rhs_c_bmd", "rhs_c_bmp", "rhs_c_bmp3", "rhs_c_a2port_armor", "rhs_c_btr", "rhs_c_sprut", "rhs_c_t72", "rhs_c_tanks", "rhs_c_a2port_air", "rhs_c_a2port_car", "rhs_c_cars", "rhs_c_trucks", "rhs_c_2s3", "rhs_c_rva", "rhs_c_heavyweapons"}; author = ECSTRING(common,ACETeam); authors[] = {"Ruthberg", "GitHawk", "BaerMitUmlaut", "commy2", "Skengman2"}; url = ECSTRING(main,URL); @@ -19,3 +20,5 @@ class CfgPatches { #include "CfgMagazines.hpp" #include "CfgWeapons.hpp" #include "CfgVehicles.hpp" +#include "CfgMagazineGroups.hpp" + diff --git a/optionals/compat_rhs_gref3/CfgVehicles.hpp b/optionals/compat_rhs_gref3/CfgVehicles.hpp index 3ac81df2fe..94beb20e53 100644 --- a/optionals/compat_rhs_gref3/CfgVehicles.hpp +++ b/optionals/compat_rhs_gref3/CfgVehicles.hpp @@ -4,4 +4,25 @@ class CfgVehicles { // Canoes are propelled by paddlers EGVAR(refuel,canReceive) = 0; }; + + class StaticMGWeapon; + class rhs_DSHKM_base: StaticMGWeapon { + // ENABLE_CSW_ATTRIBUTE; + class ACE_CSW { + enabled = 1; + proxyWeapon = QGVAR(rhs_weap_DSHKM); + magazineLocation = "_target selectionPosition 'otocvez'"; + disassembleWeapon = QGVAR(dshkm_carry); + disassembleTurret = QEGVAR(csw,kordTripod); + desiredAmmo = 50; + ammoLoadTime = 10; + ammoUnloadTime = 8; + }; + }; + class rhs_DSHkM_Mini_TriPod_base: rhs_DSHKM_base { + class ACE_CSW: ACE_CSW { + enabled = 1; + disassembleTurret = QEGVAR(csw,kordTripodLow); + }; + }; }; diff --git a/optionals/compat_rhs_gref3/CfgWeapons.hpp b/optionals/compat_rhs_gref3/CfgWeapons.hpp index d851d598e0..18681cae13 100644 --- a/optionals/compat_rhs_gref3/CfgWeapons.hpp +++ b/optionals/compat_rhs_gref3/CfgWeapons.hpp @@ -1,4 +1,3 @@ - class CfgWeapons { class rhs_weap_kar98k_Base_F; class rhs_weap_kar98k: rhs_weap_kar98k_Base_F { @@ -81,4 +80,31 @@ class CfgWeapons { class rhs_weap_mg42_base: Rifle_Base_F { ACE_Overheating_allowSwapBarrel = 1; }; + + CREATE_CSW_PROXY(rhs_weap_DSHKM); + + class Launcher; + class Launcher_Base_F: Launcher { + class WeaponSlotsInfo; + }; + class GVAR(dshkm_carry): Launcher_Base_F { + class ACE_CSW { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + EGVAR(csw,kordTripod) = "rhsgref_ins_DSHKM"; + EGVAR(csw,kordTripodLow) = "rhsgref_ins_DSHKM_Mini_TriPod"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 740; + }; + displayName = ECSTRING(csw,dshk_gun); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = "\rhsafrf\addons\rhs_heavyweapons\data\mapico\icomap_DShKM_CA.paa"; + }; }; diff --git a/optionals/compat_rhs_gref3/config.cpp b/optionals/compat_rhs_gref3/config.cpp index a8f8e14773..b5aae10911 100644 --- a/optionals/compat_rhs_gref3/config.cpp +++ b/optionals/compat_rhs_gref3/config.cpp @@ -1,4 +1,5 @@ #include "script_component.hpp" +#include "\z\ace\addons\csw\script_config_macros_csw.hpp" class CfgPatches { class ADDON { @@ -6,7 +7,7 @@ class CfgPatches { units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"rhsgref_main", "rhsgref_c_weapons"}; + requiredAddons[] = {"ace_csw", "rhsgref_main", "rhsgref_c_weapons"}; author = ECSTRING(common,ACETeam); authors[] = {"PabstMirror", "Ruthberg", "Anton"}; url = ECSTRING(main,URL); diff --git a/optionals/compat_rhs_usf3/CfgAmmo.hpp b/optionals/compat_rhs_usf3/CfgAmmo.hpp index ee2540e234..471c5d4dd3 100644 --- a/optionals/compat_rhs_usf3/CfgAmmo.hpp +++ b/optionals/compat_rhs_usf3/CfgAmmo.hpp @@ -136,17 +136,18 @@ class CfgAmmo { ACE_muzzleVelocities[] = {875, 910, 930, 945}; ACE_barrelLengths[] = {330.2, 406.4, 508.0, 609.6}; }; - class rhs_ammo_46x30_FMJ: rhs_ammo_556x45_M855A1_Ball { // RUAG Ammotec - ACE_caliber = 4.65; + class rhs_ammo_46x30_FMJ: rhs_ammo_556x45_M855A1_Ball { // RUAG Ammotec: https://www.heckler-koch.com/en/products/military/submachine-guns/mp7a1/mp7a2/ammunition.html + ACE_caliber = 4.65; // https://bobp.cip-bobp.org/uploads/tdcc/tab-i/4-6-x-30-en.pdf ACE_bulletLength = 21; ACE_bulletMass = 2.6; ACE_ammoTempMuzzleVelocityShifts[] = {-2.655, -2.547, -2.285, -2.012, -1.698, -1.280, -0.764, -0.153, 0.596, 1.517, 2.619}; - ACE_ballisticCoefficients[] = {0.171}; + ACE_ballisticCoefficients[] = {0.089}; ACE_velocityBoundaries[] = {}; ACE_standardAtmosphere = "ICAO"; - ACE_dragModel = 1; - ACE_muzzleVelocities[] = {620}; + ACE_dragModel = 7; + ACE_muzzleVelocities[] = {621}; // at 21°C, 620 m/s at 15°C according with the 4.6x30 FMJ magazine initSpeed ACE_barrelLengths[] = {180}; + airFriction = -0.002635; // default RHS value -0.0027667 }; class rhs_ammo_46x30_JHP: rhs_ammo_46x30_FMJ { // RUAG Ammotec ACE_caliber = 4.65; @@ -157,8 +158,9 @@ class CfgAmmo { ACE_velocityBoundaries[] = {}; ACE_standardAtmosphere = "ICAO"; ACE_dragModel = 1; - ACE_muzzleVelocities[] = {690}; + ACE_muzzleVelocities[] = {691}; // at 21°C, 690 m/s at 15°C according with the 4.6x30 JHP magazine initSpeed ACE_barrelLengths[] = {180}; + airFriction = -0.003723; // default RHS value -0.00348301 }; class rhs_ammo_46x30_AP: rhs_ammo_46x30_FMJ { // RUAG Ammotec ACE_caliber = 4.65; @@ -169,8 +171,9 @@ class CfgAmmo { ACE_velocityBoundaries[] = {}; ACE_standardAtmosphere = "ICAO"; ACE_dragModel = 1; - ACE_muzzleVelocities[] = {680}; + ACE_muzzleVelocities[] = {681}; // at 21°C, 680 m/s at 15°C according with the 4.6x30 AP magazine initSpeed ACE_barrelLengths[] = {180}; + airFriction = -0.003045; // default RHS value -0.00266241 }; class rhs_ammo_45ACP_MHP: BulletBase { // B_45ACP_Ball (ballistics/CfgAmmo.hpp) ACE_caliber = 11.481; @@ -294,4 +297,23 @@ class CfgAmmo { class rhs_ammo_smaw_SR: RocketBase { ACE_caliber = 9; }; + + class PipeBombBase; + class rhsusf_m112_ammo: PipeBombBase { + ace_explosives_magazine = "rhsusf_m112_mag"; + ace_explosives_Explosive = "rhsusf_m112_ammo_scripted"; + ace_explosives_size = 0; + ace_explosives_defuseObjectPosition[] = {-0.155,0,0.01}; + soundActivation[] = {"", 0, 0, 0}; + soundDeactivation[] = {"", 0, 0, 0}; + }; + + class rhsusf_m112x4_ammo: PipeBombBase { + ace_explosives_magazine = "rhsusf_m112x4_mag"; + ace_explosives_Explosive = "rhsusf_m112x4_ammo_scripted"; + ace_explosives_size = 0; + ace_explosives_defuseObjectPosition[] = {-0.155,0.025,0.01}; + soundActivation[] = {"", 0, 0, 0}; + soundDeactivation[] = {"", 0, 0, 0}; + }; }; diff --git a/optionals/compat_rhs_usf3/CfgMagazineGroups.hpp b/optionals/compat_rhs_usf3/CfgMagazineGroups.hpp new file mode 100644 index 0000000000..44d29c1f8a --- /dev/null +++ b/optionals/compat_rhs_usf3/CfgMagazineGroups.hpp @@ -0,0 +1,24 @@ +#define CREATE_MAGAZINE_GROUP(ammo) class GVAR(ammo) { rhs_##ammo = 1; } +class ace_csw_groups { + CREATE_MAGAZINE_GROUP(mag_TOW); + CREATE_MAGAZINE_GROUP(mag_TOWB); + CREATE_MAGAZINE_GROUP(mag_ITOW); + CREATE_MAGAZINE_GROUP(mag_TOW2); + CREATE_MAGAZINE_GROUP(mag_TOW2A); + CREATE_MAGAZINE_GROUP(mag_TOW2b); + CREATE_MAGAZINE_GROUP(mag_TOW2b_aero); + CREATE_MAGAZINE_GROUP(mag_TOW2bb); + class GVAR(48Rnd_40mm_MK19) { + RHS_48Rnd_40mm_MK19 = 1; + RHS_96Rnd_40mm_MK19 = 1; + }; + class GVAR(48Rnd_40mm_MK19_M430I) { + RHS_48Rnd_40mm_MK19_M430I = 1; + RHS_96Rnd_40mm_MK19_M430I = 1; + }; + class GVAR(48Rnd_40mm_MK19_M1001) { + RHS_48Rnd_40mm_MK19_M1001 = 1; + RHS_96Rnd_40mm_MK19_M1001 = 1; + }; +}; + diff --git a/optionals/compat_rhs_usf3/CfgMagazines.hpp b/optionals/compat_rhs_usf3/CfgMagazines.hpp index 1f692792f0..61d6493079 100644 --- a/optionals/compat_rhs_usf3/CfgMagazines.hpp +++ b/optionals/compat_rhs_usf3/CfgMagazines.hpp @@ -1,6 +1,21 @@ class cfgMagazines { class CA_Magazine; class VehicleMagazine; + class rhsusf_mag_40Rnd_46x30_AP: CA_Magazine { + descriptionShort = "Caliber: 4.6x30 mm
Rounds: 40
Used in: MP7A2"; + initSpeed = 680; // according with the ACE_muzzleVelocities at 15°C, default RHS value 680.1 + }; + class rhsusf_mag_40Rnd_46x30_FMJ: CA_Magazine { + descriptionShort = "Caliber: 4.6x30 mm
Rounds: 40
Used in: MP7A2"; + initSpeed = 620; // default RHS value according with the ACE_muzzleVelocities at 15°C + lastRoundsTracer = 0; + picture = "\rhsusf\addons\rhsusf_weapons2\glock17g4\data\rhs_mag1_glock17g4_ca.paa"; + tracersEvery = 0; + }; + class rhsusf_mag_40Rnd_46x30_JHP: CA_Magazine { + descriptionShort = "Caliber: 4.6x30 mm
Rounds: 40
Used in: MP7A2"; + initSpeed = 690; // according with the ACE_muzzleVelocities at 15°C, default RHS value 620 + }; class rhs_mag_30Rnd_556x45_M855A1_Stanag; class rhsusf_100Rnd_556x45_soft_pouch: rhs_mag_30Rnd_556x45_M855A1_Stanag { @@ -36,4 +51,161 @@ class cfgMagazines { ammo = "ACE_Hellfire_AGM114N"; }; + class rhsusf_m112_mag: CA_Magazine { + ace_explosives_DelayTime = 1; + ace_explosives_Placeable = 1; + ace_explosives_SetupObject = "ACE_Explosives_Place_rhsusf_m112_DemoCharge"; + useAction = 0; + class ACE_Triggers { + SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "DeadmanSwitch"}; + class Timer { + FuseTime = 0.5; + }; + class Command { + FuseTime = 0.5; + }; + class MK16_Transmitter: Command {}; + class DeadmanSwitch: Command {}; + }; + }; + + class rhsusf_m112x4_mag: rhsusf_m112_mag { + ace_explosives_DelayTime = 1; + ace_explosives_Placeable = 1; + ace_explosives_SetupObject = "ACE_Explosives_Place_rhsusf_m112x4_DemoCharge"; + useAction = 0; + class ACE_Triggers { + SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "DeadmanSwitch"}; + class Timer { + FuseTime = 0.5; + }; + class Command { + FuseTime = 0.5; + }; + class MK16_Transmitter: Command {}; + class DeadmanSwitch: Command {}; + }; + }; + + class ATMine_Range_Mag; + class rhs_mine_M19_mag: ATMine_Range_Mag { + ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_M19_Mine"; + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.075; + }; + }; + }; + + class rhsusf_mine_m14_mag: ATMine_Range_Mag { + ace_explosives_SetupObject = "ACE_Explosives_Place_rhsusf_mine_m14_mag_Mine"; + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.03; + }; + }; + }; + + // RHS magazines for crew handled ammo + class rhs_mag_TOW; + class GVAR(mag_TOW): rhs_mag_TOW { + scope = 2; + type = 256; + count = 1; + mass = 200; // Actually should be 440 but ARMA uses weight and volume in the same number + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; // ammo can instead of any special model so no one gets especially confused over what it is + picture = "\A3\Weapons_F_beta\Launchers\titan\Data\UI\gear_titan_missile_at_CA.paa"; + }; + class rhs_mag_TOWB; + class GVAR(mag_TOWB): rhs_mag_TOWB { + scope = 2; + type = 256; + count = 1; + mass = 200; + 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 rhs_mag_ITOW; + class GVAR(mag_ITOW): rhs_mag_ITOW { + scope = 2; + type = 256; + count = 1; + mass = 200; + 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 rhs_mag_TOW2; + class GVAR(mag_TOW2): rhs_mag_TOW2 { + scope = 2; + type = 256; + count = 1; + mass = 200; + 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 rhs_mag_TOW2A; + class GVAR(mag_TOW2A): rhs_mag_TOW2A { + scope = 2; + type = 256; + count = 1; + mass = 200; + 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 rhs_mag_TOW2b; + class GVAR(mag_TOW2b): rhs_mag_TOW2b { + scope = 2; + type = 256; + count = 1; + mass = 200; + 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 rhs_mag_TOW2b_aero; + class GVAR(mag_TOW2b_aero): rhs_mag_TOW2b_aero { + scope = 2; + type = 256; + count = 1; + mass = 200; + 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 rhs_mag_TOW2bb; + class GVAR(mag_TOW2bb): rhs_mag_TOW2bb { + scope = 2; + type = 256; + count = 1; + mass = 200; + 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 GVAR(48Rnd_40mm_MK19): RHS_48Rnd_40mm_MK19 { + scope = 2; + type = 256; + count = 48; + mass = 40; + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; // ammo can instead of any special model so no one gets especially confused over what it is + picture = QPATHTOEF(csw,UI\ammoBox_50bmg_ca.paa); + }; + class RHS_48Rnd_40mm_MK19_M430I; + class GVAR(48Rnd_40mm_MK19_M430I): RHS_48Rnd_40mm_MK19_M430I { + scope = 2; + type = 256; + count = 48; + mass = 40; + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; // ammo can instead of any special model so no one gets especially confused over what it is + picture = QPATHTOEF(csw,UI\ammoBox_50bmg_ca.paa); + }; + class RHS_48Rnd_40mm_MK19_M1001; + class GVAR(48Rnd_40mm_MK19_M1001): RHS_48Rnd_40mm_MK19_M1001 { + scope = 2; + type = 256; + count = 48; + mass = 40; + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; // ammo can instead of any special model so no one gets especially confused over what it is + picture = QPATHTOEF(csw,UI\ammoBox_50bmg_ca.paa); + }; }; diff --git a/optionals/compat_rhs_usf3/CfgVehicles.hpp b/optionals/compat_rhs_usf3/CfgVehicles.hpp index 02c4fff408..5c68bb13c1 100644 --- a/optionals/compat_rhs_usf3/CfgVehicles.hpp +++ b/optionals/compat_rhs_usf3/CfgVehicles.hpp @@ -300,6 +300,70 @@ class CfgVehicles { selection = "main_gun"; }; }; + // ENABLE_CSW_ATTRIBUTE; + class ACE_CSW { + enabled = 1; + magazineLocation = ""; + proxyWeapon = QGVAR(rhs_mortar_81mm); + disassembleWeapon = QGVAR(m252_carry); // carry weapon [CfgWeapons] + disassembleTurret = QEGVAR(csw,mortarBaseplate); // turret [CfgVehicles] + desiredAmmo = 1; + ammoLoadTime = 3; + ammoUnloadTime = 3; + }; + }; + + class StaticMGWeapon: StaticWeapon {}; + + class rhs_m2staticmg_base: StaticMGWeapon { + // ENABLE_CSW_ATTRIBUTE; + class ACE_CSW { + enabled = 1; + proxyWeapon = QGVAR(rhs_M2); + magazineLocation = "_target selectionPosition 'magazine'"; + disassembleWeapon = QGVAR(m2_carry); + disassembleTurret = QEGVAR(csw,m3Tripod); + desiredAmmo = 100; + ammoLoadTime = 10; + ammoUnloadTime = 8; + }; + }; + + class RHS_M2StaticMG_MiniTripod_base: rhs_m2staticmg_base { + class ACE_CSW: ACE_CSW { + enabled = 1; + disassembleTurret = QEGVAR(csw,m3TripodLow); + }; + }; + + class StaticGrenadeLauncher: StaticWeapon {}; + class RHS_MK19_TriPod_base: StaticGrenadeLauncher { + // ENABLE_CSW_ATTRIBUTE; + class ACE_CSW { + enabled = 1; + proxyWeapon = QGVAR(rhs_MK19); + magazineLocation = "_target selectionPosition 'magazine'"; + disassembleWeapon = QGVAR(mk19_carry); + disassembleTurret = QEGVAR(csw,m3TripodLow); + desiredAmmo = 48; + ammoLoadTime = 10; + ammoUnloadTime = 8; + }; + }; + + class StaticATWeapon: StaticWeapon {}; + class RHS_TOW_TriPod_base: StaticATWeapon { + // ENABLE_CSW_ATTRIBUTE; + class ACE_CSW { + enabled = 1; + proxyWeapon = QGVAR(rhs_weap_TOW_Launcher_static); + magazineLocation = "_target selectionPosition 'tube'"; + disassembleWeapon = QGVAR(tow_carry); + disassembleTurret = QEGVAR(csw,m220Tripod); + desiredAmmo = 1; + ammoLoadTime = 8; + ammoUnloadTime = 5; + }; }; class rhsusf_infantry_usmc_base; @@ -316,4 +380,51 @@ class CfgVehicles { class rhsusf_airforce_jetpilot: rhsusf_usmc_marpat_wd_rifleman_m4 { ace_gforcecoef = 0.55; }; + + class Items_base_F; + class ACE_Explosives_Place: Items_base_F { + class ACE_Actions { + class ACE_MainActions; + }; + }; + + class ACE_Explosives_Place_rhsusf_m112_DemoCharge: ACE_Explosives_Place { + displayName = "$STR_RHSUSF_M112_EXPLOSIVE_DISPLAY_NAME"; + model = "\rhsusf\addons\rhsusf_weapons\explosives\rhsusf_m112x1_e"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.155,0,0.01]"; + }; + }; + }; + + class ACE_Explosives_Place_rhsusf_m112x4_DemoCharge: ACE_Explosives_Place { + displayName = "$STR_RHSUSF_M112X4_EXPLOSIVE_DISPLAY_NAME"; + model = "\rhsusf\addons\rhsusf_weapons\explosives\rhsusf_m112x4_e"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.155,0.025,0.01]"; + }; + }; + }; + + class ACE_Explosives_Place_rhs_mine_M19_Mine: ACE_Explosives_Place { + displayName = "$STR_RHSUSF_M19_ATMINE_DISPLAY_NAME"; + model = "\rhsusf\addons\rhsusf_weapons\mines\rhsusf_m19_e"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0.011,0.011,0.045]"; + }; + }; + }; + + class ACE_Explosives_Place_rhsusf_mine_m14_mag_Mine: ACE_Explosives_Place { + displayName = "$STR_RHSUSF_M14_APMINE_DISPLAY_NAME"; + model = "\rhsusf\addons\rhsusf_weapons\mines\rhsusf_m14_e"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0.02,0.015,0.02]"; + }; + }; + }; }; diff --git a/optionals/compat_rhs_usf3/CfgWeapons.hpp b/optionals/compat_rhs_usf3/CfgWeapons.hpp index b9029d5c55..f517bbb7ba 100644 --- a/optionals/compat_rhs_usf3/CfgWeapons.hpp +++ b/optionals/compat_rhs_usf3/CfgWeapons.hpp @@ -1,4 +1,3 @@ - class CfgWeapons { class NVGoggles; class rhsusf_ANPVS_14: NVGoggles { // Monocular @@ -119,9 +118,11 @@ class CfgWeapons { }; class SMG_02_base_F; class rhsusf_weap_MP7A1_base_f: SMG_02_base_F { + ACE_barrelLength = 180; + ACE_barrelTwist = 160; + ACE_IronSightBaseAngle = -0.286479; // 5 mRad POA = POI at the default discreteDistance 100 m, SMG_02_base_F default value 0.434847 + ACE_RailBaseAngle = 0; // SMG_02_base_F default value 0.0217724 ACE_RailHeightAboveBore = 5; - ACE_barrelTwist = 160.0; - ACE_barrelLength = 180.0; }; // RHS pistols class hgun_ACPC2_F; @@ -229,7 +230,10 @@ class CfgWeapons { }; }; - class Launcher_Base_F; + class Launcher; + class Launcher_Base_F: Launcher { + class WeaponSlotsInfo; + }; class rhs_weap_smaw: Launcher_Base_F { ace_reloadlaunchers_enabled = 1; ace_overpressure_angle = 45; @@ -418,4 +422,91 @@ class CfgWeapons { class RHS_jetpilot_usaf: H_HelmetB { HEARING_PROTECTION_VICCREW }; + + CREATE_CSW_PROXY(rhs_mortar_81mm); + CREATE_CSW_PROXY(RHS_M2); + CREATE_CSW_PROXY(RHS_MK19); + CREATE_CSW_PROXY(Rhs_weap_TOW_Launcher_static); + + class GVAR(m252_carry): Launcher_Base_F { + class ACE_CSW { + type = "weapon"; + deployTime = 20; + pickupTime = 25; + class assembleTo { + EGVAR(csw,mortarBaseplate) = "RHS_M252_WD"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 620; // M252 Mortar Weight + }; + displayName = ECSTRING(CSW,m252_tube); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = "\rhsusf\addons\rhsusf_heavyweapons\data\ico\RHS_M252_D_ca.paa"; + }; + + class GVAR(m2_carry): Launcher_Base_F { + class ACE_CSW { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + EGVAR(csw,m3Tripod) = "RHS_M2StaticMG_WD"; + EGVAR(csw,m3TripodLow) = "RHS_M2StaticMG_MiniTripod_WD"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 840; + }; + displayName = ECSTRING(CSW,m2_gun); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = "\rhsusf\addons\rhsusf_heavyweapons\data\ico\RHS_M2StaticMG_D_ca.paa"; + }; + + class GVAR(mk19_carry): Launcher_Base_F { + class ACE_CSW { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + EGVAR(csw,m3TripodLow) = "RHS_MK19_TriPod_WD"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 770; + }; + displayName = ECSTRING(CSW,mk19_gun); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = "\rhsusf\addons\rhsusf_heavyweapons\data\ico\RHS_MK19_TriPod_D_ca.paa"; + }; + + class GVAR(tow_carry): Launcher_Base_F { + class ACE_CSW { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + EGVAR(csw,m220Tripod) = "RHS_TOW_TriPod_WD"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 500; + }; + displayName = ECSTRING(CSW,tow_tube); + author = ECSTRING(common,ACETeam); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = "\rhsusf\addons\rhsusf_heavyweapons\data\Ico\RHS_TOW_TriPod_D_ca.paa"; + }; }; + diff --git a/optionals/compat_rhs_usf3/config.cpp b/optionals/compat_rhs_usf3/config.cpp index 59aaa625bd..246d63f5a0 100644 --- a/optionals/compat_rhs_usf3/config.cpp +++ b/optionals/compat_rhs_usf3/config.cpp @@ -1,4 +1,5 @@ #include "script_component.hpp" +#include "\z\ace\addons\csw\script_config_macros_csw.hpp" class CfgPatches { class ADDON { @@ -6,7 +7,7 @@ class CfgPatches { units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"ace_javelin", "ace_rearm", "ace_refuel", "ace_repair", "rhsusf_c_weapons", "rhsusf_c_troops", "rhsusf_c_m1a1", "rhsusf_c_m1a2", "RHS_US_A2_AirImport", "rhsusf_c_m109", "rhsusf_c_HEMTT_A4", "rhsusf_c_hmmwv", "rhsusf_c_rg33", "rhsusf_c_fmtv", "rhsusf_c_m113", "RHS_US_A2Port_Armor", "rhsusf_c_melb"}; + requiredAddons[] = {"ace_explosives", "ace_javelin", "ace_rearm", "ace_refuel", "ace_repair", "ace_csw", "rhsusf_c_weapons", "rhsusf_c_troops", "rhsusf_c_m1a1", "rhsusf_c_m1a2", "RHS_US_A2_AirImport", "rhsusf_c_m109", "rhsusf_c_HEMTT_A4", "rhsusf_c_hmmwv", "rhsusf_c_rg33", "rhsusf_c_fmtv", "rhsusf_c_m113", "RHS_US_A2Port_Armor", "rhsusf_c_melb"}; author = ECSTRING(common,ACETeam); authors[] = {"Ruthberg", "GitHawk", "BaerMitUmlaut"}; url = ECSTRING(main,URL); @@ -21,3 +22,5 @@ class CfgPatches { #include "CfgWeapons.hpp" #include "CfgVehicles.hpp" #include "CfgGlasses.hpp" +#include "CfgMagazineGroups.hpp" + diff --git a/optionals/tracers/CfgAmmo.hpp b/optionals/tracers/CfgAmmo.hpp index c74d6ac708..9da774a4fb 100644 --- a/optionals/tracers/CfgAmmo.hpp +++ b/optionals/tracers/CfgAmmo.hpp @@ -88,7 +88,7 @@ class CfgAmmo { class B_338_Ball: BulletBase {model = PATHTOF(ace_TracerRed2.p3d);}; //Replaces \A3\Weapons_f\Data\bullettracer\tracer_red class B_338_NM_Ball: BulletBase {model = PATHTOF(ace_TracerRed2.p3d);}; //Replaces \A3\Weapons_f\Data\bullettracer\tracer_red - class ACE_338_NM_Ball_red : B_338_NM_Ball {model = PATHTOF(ace_TracerRed2.p3d);}; + class ACE_338_NM_Ball_green : B_338_NM_Ball {model = PATHTOF(ace_TracerGreen2.p3d);}; class ACE_338_NM_Ball_yellow : B_338_NM_Ball {model = PATHTOF(ace_TracerYellow2.p3d);}; class B_127x54_Ball: BulletBase {model = PATHTOF(ace_TracerGreen2.p3d);}; //Replaces \A3\Weapons_f\Data\bullettracer\tracer_green diff --git a/optionals/tracers/CfgMagazines.hpp b/optionals/tracers/CfgMagazines.hpp index a8d822696e..bd2919631a 100644 --- a/optionals/tracers/CfgMagazines.hpp +++ b/optionals/tracers/CfgMagazines.hpp @@ -224,22 +224,22 @@ class CfgMagazines { // 9.3x64 class 150Rnd_93x64_Mag; class ACE_150Rnd_93x64_Mag_red : 150Rnd_93x64_Mag { - ammo = "ACE_93x64_tracer_red"; + ammo = "ACE_93x64_Ball_tracer_red"; STRINGS(150Rnd_93x64_Mag_red); }; class ACE_150Rnd_93x64_Mag_yellow : 150Rnd_93x64_Mag { - ammo = "ACE_93x64_tracer_yellow"; + ammo = "ACE_93x64_Ball_tracer_yellow"; STRINGS(150Rnd_93x64_Mag_yellow); }; // .338 NM class 130Rnd_338_Mag; class ACE_130Rnd_338_Mag_green : 130Rnd_338_Mag { - ammo = "ACE_338_NM_tracer_green"; + ammo = "ACE_338_NM_Ball_green"; STRINGS(130Rnd_338_Mag_green); }; class ACE_130Rnd_338_Mag_yellow : 130Rnd_338_Mag { - ammo = "ACE_338_NM_tracer_yellow"; + ammo = "ACE_338_NM_Ball_yellow"; STRINGS(130Rnd_338_Mag_yellow); }; }; diff --git a/optionals/tracers/stringtable.xml b/optionals/tracers/stringtable.xml index acaaa60081..83726c9c16 100644 --- a/optionals/tracers/stringtable.xml +++ b/optionals/tracers/stringtable.xml @@ -1,258 +1,321 @@ - + 5.56 mm 150Rnd Reload Tracer (Green) Mag 150 Schuss 5,56 mm Nachlade-Leuchtspur (Grün) Magazin + Магазин 150 патр. 5.56 мм с послед. трас. (Зеленый) 5.56 mm 150Rnd Reload Tracer (Yellow) Mag 150 Schuss 5,56 mm Nachlade-Leuchtspur (Gelb) Magazin + Магазин 150 патр. 5.56 мм с послед. трас. (Желтый) 5.56 mm 150Rnd Tracer (Green) Mag 150 Schuss 5,56 mm Leuchtspur (Grün) Magazin + Магазин 150 патр. 5.56 мм трассирующих (Зеленый) Caliber: 5.56x45 mm Tracer - Green<br />Rounds: 150<br />Used in: SPAR-16S Kaliber: 5,56x45 mm Leuchtspur - grün<br />Schuss: 150<br />Verwendet in: SPAR-16S + Калибр: 5.56x45 мм, трассер Зеленый<br />Патронов: 150<br />Используется в: SPAR-16S 5.56 mm 150Rnd Tracer (Yellow) Mag 150 Schuss 5,56 mm Leuchtspur (Gelb) Magazin + Магазин 150 патр. 5.56 мм трассирующих (Желтый) Caliber: 5.56x45 mm Tracer - Yellow<br />Rounds: 150<br />Used in: SPAR-16S Kaliber: 5,56x45 mm Leuchtspur - gelb<br />Schuss: 150<br />Verwendet in: SPAR-16S + Калибр: 5.56x45 мм, трассер Желтый<br />Патронов: 150<br />Используется в: SPAR-16S 5.56 mm 200Rnd Reload Tracer (Green) Box 200 Schuss 5,56 mm Nachlade-Leuchtspur (Grün) Kasten + Короб 200 патр. 5.56 мм с послед. трас. (Зеленый) 5.56 mm 200Rnd Tracer (Green) Box 200 Schuss 5,56 mm Nachlade-Leuchtspur (Grün) Kasten + Короб 200 патр. 5.56 мм трассирующих (Зеленый) Caliber: 5.56x45 mm Tracer - Green<br />Rounds: 200<br />Used in: LIM-85 Kaliber: 5,56x45 mm Leuchtspur - grün<br />Schuss: 200<br />Verwendet in: LIM-85 + Калибр: 5.56x45 мм, трассер Зеленый<br />Патронов: 200<br />Используется в: LIM-85 5.8 mm 30Rnd Reload Tracer (Red) Mag 30 Schuss 5,8 mm Nachlade-Leuchtspur (Rot) Magazin + Магазин 30 патр. 5.8 мм с послед. трас. (Красный) 5.8 mm 30Rnd Reload Tracer (Yellow) Mag 30 Schuss 5,8 mm Nachlade-Leuchtspur (Gelb) Magazin + Магазин 30 патр. 5.8 мм с послед. трас. (Желтый) 5.8 mm 30Rnd Tracer (Red) Mag 30 Schuss 5,8 mm Leuchtspur (Rot) Magazin + Магазин 30 патр. 5.8 мм трассирующих (Красный) Caliber: 5.8x42 mm Tracer - Red<br />Rounds: 30<br />Used in: CAR-95, CAR-95 GL Kaliber: 5,8x42 mm Leuchtspur - rot<br />Schuss: 30<br />Verwendet in: CAR-95, CAR-95 GL + Калибр: 5.8x42 мм, трассер Красный<br />Патронов: 150<br />Используется в: CAR-95, CAR-95 GL 5.8 mm 30Rnd Tracer (Yellow) Mag 30 Schuss 5,8 mm Leuchtspur (Gelb) Magazin + Магазин 30 патр. 5.8 мм трассирующих (Желтый) Caliber: 5.8x42 mm Tracer - Yellow<br />Rounds: 30<br />Used in: CAR-95, CAR-95 GL Kaliber: 5,8x42 mm Leuchtspur - gelb<br />Schuss: 30<br />Verwendet in: CAR-95, CAR-95 GL + Калибр: 5.8x42 мм, трассер Желтый<br />Патронов: 30<br />Используется в: CAR-95, CAR-95 GL 5.8 mm 100Rnd Reload Tracer (Red) Mag 100 Schuss 5,8 mm Nachlade-Leuchtspur (Rot) Magazin + Магазин 100 патр. 5.8 мм с послед. трас. (Красный) 5.8 mm 100Rnd Reload Tracer (Yellow) Mag 100 Schuss 5,8 mm Nachlade-Leuchtspur (Gelb) Magazin + Магазин 100 патр. 5.8 мм с послед. трас. (Желтый) 5.8 mm 100Rnd Tracer (Red) Mag 100 Schuss 5,8 mm Leuchtspur (Rot) Magazin + Магазин 100 патр. 5.8 мм трассирующих (Красный) Caliber: 5.8x42 mm Tracer - Red<br />Rounds: 100<br />Used in: CAR-95-1 Kaliber: 5,8x42 mm Leuchtspur - rot<br />Schuss: 100<br />Verwendet in: CAR-95-1 + Калибр: 5.8x42 мм, трассер Красный<br />Патронов: 100<br />Используется в: CAR-95, CAR-95 GL 5.8 mm 100Rnd Tracer (Yellow) Mag 100 Schuss 5,8 mm Leuchtspur (Gelb) Magazin + Магазин 100 патр. 5.8 мм трассирующих (Желтый) Caliber: 5.8x42 mm Tracer - Yellow<br />Rounds: 100<br />Used in: CAR-95-1 Kaliber: 5,8x42 mm Leuchtspur - gelb<br />Schuss: 100<br />Verwendet in: CAR-95-1 + Калибр: 5.8x42 мм, трассер Желтый<br />Патронов: 100<br />Используется в: CAR-95, CAR-95 GL 6.5mm 30Rnd Reload Tracer (Green) Mag 30 Schuss 6.5mm Nachlade-Leuchtspur (Grün) Magazin + Магазин 30 патр. 6.5 мм с послед. трас. (Зеленый) Caliber: 6.5x39 mm Tracer - Green<br />Rounds: 30<br />Used in: MX/C/M/SW/3GL Kaliber: 6.5x39 mm Nachlade-Leuchtspur - Grün<br />Patronen: 30<br />Verwendet in: MX/C/M/SW/3GL + Калибр: 6.5x39 мм, трассер Зеленый<br />Патронов: 30<br />Используется в: MX/C/M/SW/3GL 6.5mm 30Rnd Reload Tracer (Yellow) Mag 30 Schuss 6.5mm Nachlade-Leuchtspur (Gelb) Magazin + Магазин 30 патр. 6.5 мм с послед. трас. (Желтый) Caliber: 6.5x39 mm Tracer - Yellow<br />Rounds: 30<br />Used in: MX/C/M/SW/3GL Kaliber: 6.5x39 mm Nachlade-Leuchtspur - Gelb<br />Patronen: 30<br />Verwendet in: MX/C/M/SW/3GL + Калибр: 6.5x39 мм, трассер Желтый<br />Патронов: 30<br />Используется в: MX/C/M/SW/3GL 6.5mm 30Rnd Tracer (Green) Mag 30 Schuss 6.5mm Leuchtspur (Grün) Magazin + Магазин 30 патр. 6.5 мм трассирующих (Зеленый) Caliber: 6.5x39 mm Tracer - Green<br />Rounds: 30<br />Used in: MX/C/M/SW/3GL Kaliber: 6.5x39 mm Leuchtspur - Grün<br />Patronen: 30<br />Verwendet in: MX/C/M/SW/3GL + Калибр: 6.5x39 мм, трассер Зеленый<br />Патронов: 30<br />Используется в: MX/C/M/SW/3GL 6.5mm 30Rnd Tracer (Yellow) Mag 30 Schuss 6.5mm Leuchtspur (Gelb) Magazin + Магазин 30 патр. 6.5 мм трассирующих (Желтый) Caliber: 6.5x39 mm Tracer - Yellow<br />Rounds: 30<br />Used in: MX/C/M/SW/3GL Kaliber: 6.5x39 mm Leuchtspur - Gelb<br />Patronen: 30<br />Verwendet in: MX/C/M/SW/3GL + Калибр: 6.5x39 мм, трассер Желтый<br />Патронов: 30<br />Используется в: MX/C/M/SW/3GL 6.5mm 100Rnd Mixed Mag (Green) 100 Schuss 6.5mm Magazin gemischt (grün) + Магазин 100 патр. 6.5 мм TE4 (Зеленый) 6.5mm 100Rnd Mixed Mag (Yellow) 100 Schuss 6.5mm Magazin gemischt (gelb) + Магазин 100 патр. 6.5 мм TE4 (Желтый) 6.5mm 100Rnd Mag Tracer (Green) 100 Schuss 6.5mm Magazin Leuchtspur (Grün) + Магазин 100 патр. 6.5 мм трассирующих (Зеленый) Caliber: 6.5x39 mm Tracer - Green<br />Rounds: 100<br />Used in: MX SW Kaliber: 6.5x39 mm Leuchtspur - Grün<br />Patronen: 100<br />Verwendet in: MX SW + Калибр: 6.5x39 мм, трассер Зеленый<br />Патронов: 100<br />Используется в: MX SW 6.5mm 100Rnd Mag Tracer (Yellow) 100 Schuss 6.5mm Magazin Leuchtspur (Gelb) + Магазин 100 патр. 6.5 мм трассирующих (Желтый) Caliber: 6.5x39 mm Tracer - Yellow<br />Rounds: 100<br />Used in: MX SW Kaliber: 6.5x39 mm Leuchtspur - Gelb<br />Patronen: 100<br />Verwendet in: MX SW + Калибр: 6.5x39 мм, трассер Желтый<br />Патронов: 100<br />Используется в: MX SW 6.5mm 30Rnd Reload Tracer (Red) Mag 30 Schuss 6.5mm Nachlade-Leuchtspur (Rot) Magazin + Магазин 30 патр. 6.5 мм с послед. трас. (Красный) 6.5mm 30Rnd Reload Tracer (Yellow) Mag 30 Schuss 6.5mm Nachlade-Leuchtspur (Gelb) Magazin + Магазин 30 патр. 6.5 мм с послед. трас. (Желтый) 6.5mm 30Rnd Tracer (Red) Mag 30 Schuss 6.5mm Leuchtspur (Rot) Magazin + Магазин 30 патр. 6.5 мм трассирующих (Красный) Caliber: 6.5x39 mm Tracer (Red) - Caseless<br />Rounds: 30<br />Used in: Katiba, Type 115 Kaliber: 6,5x39mm Leuchtspur (Rot) ‒ hülsenlos<br />Patronen: 30<br />Eingesetzt von: Katiba, Typ 115 + Калибр: 6.5x39 мм, трассер Красный безгильзовый<br />Патронов: 30<br />Используется в: Katiba, Type 115 6.5mm 30Rnd Tracer (Yellow) Mag 30 Schuss 6.5mm Leuchtspur (Gelb) Magazin + Магазин 30 патр. 6.5 мм трассирующих (Желтый) Caliber: 6.5x39 mm Tracer (Yellow) - Caseless<br />Rounds: 30<br />Used in: Katiba, Type 115 Kaliber: 6,5x39mm Leuchtspur (Rot) ‒ hülsenlos<br />Patronen: 30<br />Eingesetzt von: Katiba, Typ 115 + Калибр: 6.5x39 мм, трассер Желтый безгильзовый<br />Патронов: 30<br />Используется в: Katiba, Type 115 6.5 mm 200Rnd Belt Case Mixed (Green) 6,5 mm 200-Schuss-Gurtkiste Gemischt (grün) + Короб 200 патр. 6.5 мм TE4 (Зеленый) Caliber: 6.5x39 mm Mixed - Green<br />Rounds: 200<br />Used in: Mk200 Kaliber: 6.5x39 mm Gemischt - Grün<br />Patronen: 200<br />Verwendet in: Mk200 + Калибр: 6.5x39 мм, трассер каждый 4 Зеленый<br />Патронов: 200<br />Используется в: Mk200 6.5 mm 200Rnd Belt Case Mixed (Red) 6,5 mm 200-Schuss-Gurtkiste Gemischt (grün) + Короб 200 патр. 6.5 мм TE4 (Красный) Caliber: 6.5x39 mm Mixed - Red<br />Rounds: 200<br />Used in: Mk200 Kaliber: 6.5x39 mm Mixed - Rot<br />Patronen: 200<br />Verwendet in: Mk200 + Калибр: 6.5x39 мм, трассер каждый 4 Красный<br />Патронов: 200<br />Используется в: Mk200 6.5 mm 200Rnd Belt Case Tracer (Green) 6,5 mm 200-Schuss-Gurtkiste Leuchtspur (grün) + Короб 200 патр. 6.5 мм трассирующих (Зеленый) Caliber: 6.5x39 mm Tracer - Green<br />Rounds: 200<br />Used in: Mk200 Kaliber: 6.5x39 mm Leuchtspur - Grün<br />Patronen: 200<br />Verwendet in: Mk200 + Калибр: 6.5x39 мм, трассер Зеленый<br />Патронов: 200<br />Используется в: Mk200 6.5 mm 200Rnd Belt Case Tracer (Red) 6,5 mm 200-Schuss-Gurtkiste Leuchtspur (rot) + Короб 200 патр. 6.5 мм трассирующих (Красный) Caliber: 6.5x39 mm Tracer - Red<br />Rounds: 200<br />Used in: Mk200 Kaliber: 6.5x39 mm Leuchtspur - Rot<br />Patronen: 200<br />Verwendet in: Mk200 + Калибр: 6.5x39 мм, трассер Красный<br />Патронов: 200<br />Используется в: Mk200 7.62 mm 20Rnd Tracer (Green) Mag 7,62 mm 20-Schuss-Magazin Leuchtspur (Grün) + Магазин 20 патр. 7.62 мм трассирующих (Зеленый) Caliber: 7.62x51 mm NATO Tracer - Green<br />Rounds: 20<br />Used in: Mk18 ABR, Mk-I EMR, Mk14, SPAR-17 Kaliber: 7,62x51 mm NATO Leuchtspur - grün<br />Patronen: 20<br />Eingesetzt von: Mk18 ABR, Mk-I EMR, Mk14, SPAR-17 + Калибр: 7.62x51 mm NATO, трассер Зеленый<br />Патронов: 20<br />Используется в: Mk18 ABR, Mk-I EMR, Mk14, SPAR-17 7.62 mm 20Rnd Tracer (Yellow) Mag 7,62 mm 20-Schuss-Magazin Leuchtspur (Gelb) + Магазин 20 патр. 7.62 мм трассирующих (Желтый) Caliber: 7.62x51 mm NATO Tracer - Yellow<br />Rounds: 20<br />Used in: Mk18 ABR, Mk-I EMR, Mk14, SPAR-17 Kaliber: 7,62x51 mm NATO Leuchtspur - gelb<br />Patronen: 20<br />Eingesetzt von: Mk18 ABR, Mk-I EMR, Mk14, SPAR-17 + Калибр: 7.62x51 mm NATO, трассер Желтый<br />Патронов: 20<br />Используется в: Mk18 ABR, Mk-I EMR, Mk14, SPAR-17 7.62mm 150Rnd Box Mixed (Red) 7.62mm 150 Schuss Kiste Gemischt (rot) + Короб 150 патр. 7.62 мм TE4 (Красный) 7.62mm 150Rnd Box Mixed (Yellow) 7.62mm 150 Schuss Kiste Gemischt (gelb) + Короб 150 патр. 7.62 мм TE4 (Желтый) 7.62mm 150Rnd Box Tracer (Red) 7.62mm 150 Schuss Kiste Leuchtspur (rot) + Короб 150 патр. 7.62 мм трассирующих (Красный) Caliber: 7.62x54 mm Tracer - Red<br />Rounds: 150<br />Used in: Zafir Kaliber: 7.62x54 mm Leuchtspur - Rot<br />Patronen: 150<br />Verwendet in: Zafir + Калибр: 7.62x51 mm NATO, трассер Красный<br />Патронов: 150<br />Используется в: Zafir 7.62mm 150Rnd Box Tracer (Yellow) 7.62mm 150 Schuss Kiste Leuchtspur (Rot) + Короб 150 патр. 7.62 мм трассирующих (Желтый) Caliber: 7.62x54 mm Tracer - Yellow<br />Rounds: 150<br />Used in: Zafir Kaliber: 7.62x54 mm Leuchtspur - Gelb<br />Patronen: 150<br />Verwendet in: Zafir + Калибр: 7.62x51 mm NATO, трассер Желтый<br />Патронов: 150<br />Используется в: Zafir 9.3mm 150Rnd Belt Mixed (Yellow) 9.3mm 150 Schuss Gurt gemischt (Gelb) + Лента 150 патр. 9.3 мм TE4 (Желтый) 9.3mm 150Rnd Belt Mixed (Red) 9.3mm 150 Schuss Gurt gemischt (Rot) + Лента 150 патр. 9.3 мм TE4 (Красный) .338 NM 130Rnd Belt Mixed (Yellow) .338 NM 130 Schuss Gurt gemischt (gelb) + Лента 130 патр. .338 NM TE4 (Желтый) .338 NM 130Rnd Belt Mixed (Green) .338 NM 130 Schuss Gurt gemischt (grün) + Лента 130 патр. .338 NM TE4 (Зеленый) diff --git a/tools/deploy.py b/tools/deploy.py index 42b5a825a3..32dade9c3f 100644 --- a/tools/deploy.py +++ b/tools/deploy.py @@ -27,6 +27,8 @@ REPOUSER = "acemod" REPONAME = "ACE3" REPOPATH = "{}/{}".format(REPOUSER,REPONAME) +BRANCH = "master" + def update_translations(repo): diag = sp.check_output(["python3", "tools/stringtablediag.py", "--markdown"]) @@ -41,14 +43,11 @@ def update_dependencies(repo): diff = str(diff, "utf-8") if diff != "": - sha = repo.get_contents(DEPENDENCIESPATH - #, ref="travisForDocs" # Debug - ).sha + sha = repo.get_contents(DEPENDENCIESPATH, ref=BRANCH).sha repo.update_file( - path="/{}".format(DEPENDENCIESPATH), - message="[Docs] Update component dependencies\nAutomatically committed through Travis CI.\n\n[ci skip]", - content=dependencies, sha=sha, committer=InputGitAuthor("ace3mod", "ace3mod@gmail.com") - #, branch="travisForDocs" # Debug + path="{}".format(DEPENDENCIESPATH), + message="[Docs] Update component dependencies\nAutomatically committed through CI.\n\n[ci skip]", + content=dependencies, sha=sha, committer=InputGitAuthor("ace3mod", "ace3mod@gmail.com"), branch=BRANCH ) print("Dependencies successfully updated.") else: diff --git a/tools/make.py b/tools/make.py index 8e4509e162..ccb9d75d92 100644 --- a/tools/make.py +++ b/tools/make.py @@ -334,11 +334,11 @@ def copy_important_files(source_dir,destination_dir): print_error("COPYING IMPORTANT FILES.") raise - # Copy all extension DLL's + # Copy all extensions try: os.chdir(os.path.join(source_dir)) print_blue("\nSearching for DLLs in {}".format(os.getcwd())) - filenames = glob.glob("*.dll") + filenames = glob.glob("*.dll") + glob.glob("*.so") if not filenames: print ("Empty SET") diff --git a/tools/search_privates.py b/tools/search_privates.py index 1cd0b7c180..1fe5c14887 100644 --- a/tools/search_privates.py +++ b/tools/search_privates.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python3 import fnmatch import os @@ -9,105 +9,105 @@ import argparse def get_private_declare(content): priv_declared = [] - + srch = re.compile('private.*') priv_srch_declared = srch.findall(content) priv_srch_declared = sorted(set(priv_srch_declared)) - + priv_dec_str = ''.join(priv_srch_declared) - + srch = re.compile('(? 0: print (filepath) - + private_output = 'private['; first = True for bad_priv in missing: if first: first = False private_output = private_output + '"' + bad_priv - else: + else: private_output = private_output + '", "' + bad_priv - + private_output = private_output + '"];'; print (private_output) - + for bad_priv in missing: print ('\t' + bad_priv) bad_count_file = bad_count_file + 1 - - - + + + return bad_count_file - + def main(): print("#########################") @@ -116,20 +116,20 @@ def main(): sqf_list = [] bad_count = 0 - + parser = argparse.ArgumentParser() parser.add_argument('-m','--module', help='only search specified module addon folder', required=False, default=".") args = parser.parse_args() - + for root, dirnames, filenames in os.walk('../addons' + '/' + args.module): for filename in fnmatch.filter(filenames, '*.sqf'): sqf_list.append(os.path.join(root, filename)) - + for filename in sqf_list: bad_count = bad_count + check_privates(filename) - - + + print ("Bad Count {0}".format(bad_count)) - + if __name__ == "__main__": main() diff --git a/tools/search_undefinedFunctions.py b/tools/search_undefinedFunctions.py index 1c281fa717..d2ed263569 100644 --- a/tools/search_undefinedFunctions.py +++ b/tools/search_undefinedFunctions.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python3 import fnmatch import os diff --git a/tools/search_unused_privates.py b/tools/search_unused_privates.py index 72a0dadcea..04a1fc977d 100644 --- a/tools/search_unused_privates.py +++ b/tools/search_unused_privates.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python3 import fnmatch import os @@ -9,98 +9,98 @@ import argparse def get_private_declare(content): priv_declared = [] - + srch = re.compile('private.*') priv_srch_declared = srch.findall(content) priv_srch_declared = sorted(set(priv_srch_declared)) - + priv_dec_str = ''.join(priv_srch_declared) - + srch = re.compile('(? 0: print (filepath) - + private_output = 'private['; first = True for bad_priv in unused: if first: first = False private_output = private_output + '"' + bad_priv - else: + else: private_output = private_output + '", "' + bad_priv - + private_output = private_output + '"];'; print (private_output) - + for bad_priv in unused: print ('\t' + bad_priv) bad_count_file = bad_count_file + 1 - - - + + + return bad_count_file - + def main(): print("#########################") @@ -109,20 +109,20 @@ def main(): sqf_list = [] bad_count = 0 - + parser = argparse.ArgumentParser() parser.add_argument('-m','--module', help='only search specified module addon folder', required=False, default=".") args = parser.parse_args() - + for root, dirnames, filenames in os.walk('../addons' + '/' + args.module): for filename in fnmatch.filter(filenames, '*.sqf'): sqf_list.append(os.path.join(root, filename)) - + for filename in sqf_list: bad_count = bad_count + check_privates(filename) - - + + print ("Bad Count {0}".format(bad_count)) - + if __name__ == "__main__": main() diff --git a/tools/sqf_linter.py b/tools/sqf_linter.py index 46461eb357..79df39195c 100644 --- a/tools/sqf_linter.py +++ b/tools/sqf_linter.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python3 # Requires: https://github.com/LordGolias/sqf @@ -24,7 +24,7 @@ def analyze(filename, writer=sys.stdout): return 0, 1 exceptions = sqf.analyzer.analyze(result).exceptions - if (exceptions): + if (exceptions): print("{}:".format(filename)) for e in exceptions: if (e.message.startswith("error")): @@ -32,9 +32,9 @@ def analyze(filename, writer=sys.stdout): else: warnings += 1 writer.write(' [%d,%d]:%s\n' % (e.position[0], e.position[1] - 1, e.message)) - + return warnings, errors - + def main(): print("#########################") print("# Lint Check #") @@ -43,24 +43,24 @@ def main(): sqf_list = [] all_warnings = 0 all_errors = 0 - + parser = argparse.ArgumentParser() parser.add_argument('-m','--module', help='only search specified module addon folder', required=False, default=".") args = parser.parse_args() - + for root, dirnames, filenames in os.walk('../addons' + '/' + args.module): for filename in fnmatch.filter(filenames, '*.sqf'): sqf_list.append(os.path.join(root, filename)) - + for filename in sqf_list: warnings, errors = analyze(filename) all_warnings += warnings all_errors += errors - + print ("Parse Errors {0} - Warnings {1}".format(all_errors,all_warnings)) # return (all_errors + all_warnings) return all_errors - + if __name__ == "__main__": main()